[#1621] pilorama: Seek after cursor invalidation

Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
Signed-off-by: Evgenii Stratonikov <evgeniy@morphbits.ru>
This commit is contained in:
Evgenii Stratonikov 2022-07-22 09:47:12 +03:00 committed by Anton Nikiforov
parent e9ba8931f8
commit 2539d466a6
2 changed files with 8 additions and 5 deletions

View file

@ -322,6 +322,8 @@ func (t *boltForest) applyOperation(logBucket, treeBucket *bbolt.Bucket, lm *Log
key, value = c.Prev() key, value = c.Prev()
} }
key, _ = c.Next()
// 2. Insert the operation. // 2. Insert the operation.
if len(key) != 8 || binary.BigEndian.Uint64(key) != lm.Time { if len(key) != 8 || binary.BigEndian.Uint64(key) != lm.Time {
if err := t.do(logBucket, treeBucket, cKey[:], lm); err != nil { if err := t.do(logBucket, treeBucket, cKey[:], lm); err != nil {
@ -334,7 +336,7 @@ func (t *boltForest) applyOperation(logBucket, treeBucket *bbolt.Bucket, lm *Log
// Otherwise, `Next` call will return currently inserted operation. // Otherwise, `Next` call will return currently inserted operation.
c.First() c.First()
} }
key, value = c.Next() key, value = c.Seek(key)
// 3. Re-apply all other operations. // 3. Re-apply all other operations.
for len(key) == 8 { for len(key) == 8 {
@ -352,8 +354,6 @@ func (t *boltForest) applyOperation(logBucket, treeBucket *bbolt.Bucket, lm *Log
} }
func (t *boltForest) do(lb *bbolt.Bucket, b *bbolt.Bucket, key []byte, op *LogMove) error { func (t *boltForest) do(lb *bbolt.Bucket, b *bbolt.Bucket, key []byte, op *LogMove) error {
shouldPut := !t.isAncestor(b, key, op.Child, op.Parent)
currParent := b.Get(parentKey(key, op.Child)) currParent := b.Get(parentKey(key, op.Child))
op.HasOld = currParent != nil op.HasOld = currParent != nil
if currParent != nil { // node is already in tree if currParent != nil { // node is already in tree
@ -361,6 +361,9 @@ func (t *boltForest) do(lb *bbolt.Bucket, b *bbolt.Bucket, key []byte, op *LogMo
if err := op.Old.Meta.FromBytes(b.Get(metaKey(key, op.Child))); err != nil { if err := op.Old.Meta.FromBytes(b.Get(metaKey(key, op.Child))); err != nil {
return err return err
} }
} else {
op.HasOld = false
op.Old = nodeInfo{}
} }
binary.BigEndian.PutUint64(key, op.Time) binary.BigEndian.PutUint64(key, op.Time)
@ -368,7 +371,7 @@ func (t *boltForest) do(lb *bbolt.Bucket, b *bbolt.Bucket, key []byte, op *LogMo
return err return err
} }
if !shouldPut { if t.isAncestor(b, key, op.Child, op.Parent) || op.Child == op.Parent {
return nil return nil
} }

View file

@ -707,7 +707,7 @@ func testForestTreeApplyRandom(t *testing.T, constructor func(t testing.TB) Fore
for i := 0; i < iterCount; i++ { for i := 0; i < iterCount; i++ {
// Shuffle random operations, leave initialization in place. // Shuffle random operations, leave initialization in place.
rand.Shuffle(len(ops)-nodeCount, func(i, j int) { ops[i+nodeCount], ops[j+nodeCount] = ops[j+nodeCount], ops[i+nodeCount] }) rand.Shuffle(len(ops), func(i, j int) { ops[i], ops[j] = ops[j], ops[i] })
actual := constructor(t) actual := constructor(t)
for i := range ops { for i := range ops {