Skip to content

Commit 614e55d

Browse files
MauriceVanVeenwallyqs
authored andcommitted
Revert "[FIXED] Subject state consistency (#6226)"
This reverts commit 60e2982, reversing changes made to f264fb3.
1 parent b606d5b commit 614e55d

File tree

3 files changed

+30
-107
lines changed

3 files changed

+30
-107
lines changed

server/filestore.go

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2616,6 +2616,10 @@ func (fs *fileStore) numFilteredPendingWithLast(filter string, last bool, ss *Si
26162616
// Always reset.
26172617
ss.First, ss.Last, ss.Msgs = 0, 0, 0
26182618

2619+
if filter == _EMPTY_ {
2620+
filter = fwcs
2621+
}
2622+
26192623
// We do need to figure out the first and last sequences.
26202624
wc := subjectHasWildcard(filter)
26212625
start, stop := uint32(math.MaxUint32), uint32(0)
@@ -7832,6 +7836,17 @@ func (mb *msgBlock) removeSeqPerSubject(subj string, seq uint64) {
78327836

78337837
ss.Msgs--
78347838

7839+
// Only one left.
7840+
if ss.Msgs == 1 {
7841+
if seq == ss.Last {
7842+
ss.Last = ss.First
7843+
} else {
7844+
ss.First = ss.Last
7845+
}
7846+
ss.firstNeedsUpdate = false
7847+
return
7848+
}
7849+
78357850
// We can lazily calculate the first sequence when needed.
78367851
ss.firstNeedsUpdate = seq == ss.First || ss.firstNeedsUpdate
78377852
}
@@ -7857,12 +7872,8 @@ func (mb *msgBlock) recalculateFirstForSubj(subj string, startSeq uint64, ss *Si
78577872
startSlot = 0
78587873
}
78597874

7860-
fseq := startSeq + 1
7861-
if mbFseq := atomic.LoadUint64(&mb.first.seq); fseq < mbFseq {
7862-
fseq = mbFseq
7863-
}
78647875
var le = binary.LittleEndian
7865-
for slot := startSlot; slot < len(mb.cache.idx); slot++ {
7876+
for slot, fseq := startSlot, atomic.LoadUint64(&mb.first.seq); slot < len(mb.cache.idx); slot++ {
78667877
bi := mb.cache.idx[slot] &^ hbit
78677878
if bi == dbit {
78687879
// delete marker so skip.

server/memstore.go

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,9 +1009,8 @@ func (ms *memStore) Compact(seq uint64) (uint64, error) {
10091009
if sm := ms.msgs[seq]; sm != nil {
10101010
bytes += memStoreMsgSize(sm.subj, sm.hdr, sm.msg)
10111011
purged++
1012-
ms.removeSeqPerSubject(sm.subj, seq)
1013-
// Must delete message after updating per-subject info, to be consistent with file store.
10141012
delete(ms.msgs, seq)
1013+
ms.removeSeqPerSubject(sm.subj, seq)
10151014
}
10161015
}
10171016
if purged > ms.state.Msgs {
@@ -1099,9 +1098,8 @@ func (ms *memStore) Truncate(seq uint64) error {
10991098
if sm := ms.msgs[i]; sm != nil {
11001099
purged++
11011100
bytes += memStoreMsgSize(sm.subj, sm.hdr, sm.msg)
1102-
ms.removeSeqPerSubject(sm.subj, i)
1103-
// Must delete message after updating per-subject info, to be consistent with file store.
11041101
delete(ms.msgs, i)
1102+
ms.removeSeqPerSubject(sm.subj, i)
11051103
}
11061104
}
11071105
// Reset last.
@@ -1362,8 +1360,17 @@ func (ms *memStore) removeSeqPerSubject(subj string, seq uint64) {
13621360
}
13631361
ss.Msgs--
13641362

1365-
// We can lazily calculate the first sequence when needed.
1366-
ss.firstNeedsUpdate = seq == ss.First || ss.firstNeedsUpdate
1363+
// If we know we only have 1 msg left don't need to search for next first.
1364+
if ss.Msgs == 1 {
1365+
if seq == ss.Last {
1366+
ss.Last = ss.First
1367+
} else {
1368+
ss.First = ss.Last
1369+
}
1370+
ss.firstNeedsUpdate = false
1371+
} else {
1372+
ss.firstNeedsUpdate = seq == ss.First || ss.firstNeedsUpdate
1373+
}
13671374
}
13681375

13691376
// Will recalculate the first sequence for this subject in this block.
@@ -1396,6 +1403,7 @@ func (ms *memStore) removeMsg(seq uint64, secure bool) bool {
13961403

13971404
ss = memStoreMsgSize(sm.subj, sm.hdr, sm.msg)
13981405

1406+
delete(ms.msgs, seq)
13991407
if ms.state.Msgs > 0 {
14001408
ms.state.Msgs--
14011409
if ss > ms.state.Bytes {
@@ -1420,8 +1428,6 @@ func (ms *memStore) removeMsg(seq uint64, secure bool) bool {
14201428

14211429
// Remove any per subject tracking.
14221430
ms.removeSeqPerSubject(sm.subj, seq)
1423-
// Must delete message after updating per-subject info, to be consistent with file store.
1424-
delete(ms.msgs, seq)
14251431

14261432
if ms.scb != nil {
14271433
// We do not want to hold any locks here.

server/store_test.go

Lines changed: 0 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -142,100 +142,6 @@ func TestStoreDeleteRange(t *testing.T) {
142142
require_Equal(t, num, 1)
143143
}
144144

145-
func TestStoreSubjectStateConsistency(t *testing.T) {
146-
testAllStoreAllPermutations(
147-
t, false,
148-
StreamConfig{Name: "TEST", Subjects: []string{"foo"}},
149-
func(t *testing.T, fs StreamStore) {
150-
getSubjectState := func() SimpleState {
151-
t.Helper()
152-
ss := fs.SubjectsState("foo")
153-
return ss["foo"]
154-
}
155-
156-
// Publish an initial batch of messages.
157-
for i := 0; i < 4; i++ {
158-
_, _, err := fs.StoreMsg("foo", nil, nil)
159-
require_NoError(t, err)
160-
}
161-
162-
// Expect 4 msgs, with first=1, last=4.
163-
ss := getSubjectState()
164-
require_Equal(t, ss.Msgs, 4)
165-
require_Equal(t, ss.First, 1)
166-
require_Equal(t, ss.Last, 4)
167-
168-
// Remove first message, ss.First is lazy so will only mark ss.firstNeedsUpdate.
169-
removed, err := fs.RemoveMsg(1)
170-
require_NoError(t, err)
171-
require_True(t, removed)
172-
173-
// Will update first, so corrects to seq 2.
174-
ss = getSubjectState()
175-
require_Equal(t, ss.Msgs, 3)
176-
require_Equal(t, ss.First, 2)
177-
require_Equal(t, ss.Last, 4)
178-
179-
// Remove last message.
180-
removed, err = fs.RemoveMsg(4)
181-
require_NoError(t, err)
182-
require_True(t, removed)
183-
184-
// ss.Last is lazy, just like ss.First, but it's not recalculated. Only total msg count decreases.
185-
ss = getSubjectState()
186-
require_Equal(t, ss.Msgs, 2)
187-
require_Equal(t, ss.First, 2)
188-
require_Equal(t, ss.Last, 4)
189-
190-
// Remove first message again.
191-
removed, err = fs.RemoveMsg(2)
192-
require_NoError(t, err)
193-
require_True(t, removed)
194-
195-
// Since we only have one message left, must update ss.First and set ss.Last to equal.
196-
ss = getSubjectState()
197-
require_Equal(t, ss.Msgs, 1)
198-
require_Equal(t, ss.First, 3)
199-
require_Equal(t, ss.Last, 3)
200-
201-
// Publish some more messages so we can test another scenario.
202-
for i := 0; i < 3; i++ {
203-
_, _, err := fs.StoreMsg("foo", nil, nil)
204-
require_NoError(t, err)
205-
}
206-
207-
// Just check the state is complete again.
208-
ss = getSubjectState()
209-
require_Equal(t, ss.Msgs, 4)
210-
require_Equal(t, ss.First, 3)
211-
require_Equal(t, ss.Last, 7)
212-
213-
// Remove last sequence, ss.Last is lazy so doesn't get updated.
214-
removed, err = fs.RemoveMsg(7)
215-
require_NoError(t, err)
216-
require_True(t, removed)
217-
218-
// Remove first sequence, ss.First is lazy so doesn't get updated.
219-
removed, err = fs.RemoveMsg(3)
220-
require_NoError(t, err)
221-
require_True(t, removed)
222-
223-
// Remove (now) first sequence, but because ss.First is lazy we first need to recalculate
224-
// to know seq 5 became ss.First. And since we're removing seq 5 we need to recalculate ss.First
225-
// yet again, since ss.Last is lazy and is not correct.
226-
removed, err = fs.RemoveMsg(5)
227-
require_NoError(t, err)
228-
require_True(t, removed)
229-
230-
// ss.First should equal ss.Last, last should have been updated now.
231-
ss = getSubjectState()
232-
require_Equal(t, ss.Msgs, 1)
233-
require_Equal(t, ss.First, 6)
234-
require_Equal(t, ss.Last, 6)
235-
},
236-
)
237-
}
238-
239145
func TestStoreMaxMsgsPerUpdateBug(t *testing.T) {
240146
config := func() StreamConfig {
241147
return StreamConfig{Name: "TEST", Subjects: []string{"foo"}, MaxMsgsPer: 0}

0 commit comments

Comments
 (0)