From 428d21f5eb6035269b8c7ed9884630e1b1113d41 Mon Sep 17 00:00:00 2001 From: wayblink Date: Thu, 16 Jun 2022 16:33:20 +0800 Subject: [PATCH] mvcc:add ut for Revisions/CountRevisions and remove RangeSince as it is not used Signed-off-by: wayblink --- server/storage/mvcc/index.go | 32 +++---------- server/storage/mvcc/index_test.go | 75 +++++++++++++++++++++++-------- 2 files changed, 62 insertions(+), 45 deletions(-) diff --git a/server/storage/mvcc/index.go b/server/storage/mvcc/index.go index eb8b82d2a..954121757 100644 --- a/server/storage/mvcc/index.go +++ b/server/storage/mvcc/index.go @@ -15,7 +15,6 @@ package mvcc import ( - "sort" "sync" "github.com/google/btree" @@ -29,7 +28,6 @@ type index interface { CountRevisions(key, end []byte, atRev int64) int Put(key []byte, rev revision) Tombstone(key []byte, rev revision) error - RangeSince(key, end []byte, rev int64) []revision Compact(rev int64) map[revision]struct{} Keep(rev int64) map[revision]struct{} Equal(b index) bool @@ -107,6 +105,9 @@ func (ti *treeIndex) unsafeVisit(key, end []byte, f func(ki *keyIndex) bool) { }) } +// Revisions returns limited number of revisions from key(included) to end(excluded) +// at the given rev. The returned slice is sorted in the order of key. There is no limit if limit <= 0. +// The second return parameter isn't capped by the limit and reflects the total number of revisions. func (ti *treeIndex) Revisions(key, end []byte, atRev int64, limit int) (revs []revision, total int) { ti.RLock() defer ti.RUnlock() @@ -130,6 +131,8 @@ func (ti *treeIndex) Revisions(key, end []byte, atRev int64, limit int) (revs [] return revs, total } +// CountRevisions returns the number of revisions +// from key(included) to end(excluded) at the given rev. func (ti *treeIndex) CountRevisions(key, end []byte, atRev int64) int { ti.RLock() defer ti.RUnlock() @@ -186,31 +189,6 @@ func (ti *treeIndex) Tombstone(key []byte, rev revision) error { return ki.tombstone(ti.lg, rev.main, rev.sub) } -// RangeSince returns all revisions from key(including) to end(excluding) -// at or after the given rev. The returned slice is sorted in the order -// of revision. -func (ti *treeIndex) RangeSince(key, end []byte, rev int64) []revision { - ti.RLock() - defer ti.RUnlock() - - if end == nil { - keyi := ti.keyIndex(&keyIndex{key: key}) - if keyi == nil { - return nil - } - return keyi.since(ti.lg, rev) - } - - var revs []revision - ti.unsafeVisit(key, end, func(ki *keyIndex) bool { - revs = append(revs, ki.since(ti.lg, rev)...) - return true - }) - sort.Sort(revisions(revs)) - - return revs -} - func (ti *treeIndex) Compact(rev int64) map[revision]struct{} { available := make(map[revision]struct{}) ti.lg.Info("compact tree index", zap.Int64("revision", rev)) diff --git a/server/storage/mvcc/index_test.go b/server/storage/mvcc/index_test.go index dd65e661d..8fd5f6c74 100644 --- a/server/storage/mvcc/index_test.go +++ b/server/storage/mvcc/index_test.go @@ -139,7 +139,7 @@ func TestIndexTombstone(t *testing.T) { } } -func TestIndexRangeSince(t *testing.T) { +func TestIndexRevision(t *testing.T) { allKeys := [][]byte{[]byte("foo"), []byte("foo1"), []byte("foo2"), []byte("foo2"), []byte("foo1"), []byte("foo")} allRevs := []revision{{main: 1}, {main: 2}, {main: 3}, {main: 4}, {main: 5}, {main: 6}} @@ -148,48 +148,87 @@ func TestIndexRangeSince(t *testing.T) { ti.Put(allKeys[i], allRevs[i]) } - atRev := int64(1) tests := []struct { key, end []byte + atRev int64 + limit int wrevs []revision + wcounts int }{ // single key that not found { - []byte("bar"), nil, nil, + []byte("bar"), nil, 6, 0, nil, 0, }, // single key that found { - []byte("foo"), nil, []revision{{main: 1}, {main: 6}}, + []byte("foo"), nil, 6, 0, []revision{{main: 6}}, 1, }, - // range keys, return first member + // various range keys, fixed atRev, unlimited { - []byte("foo"), []byte("foo1"), []revision{{main: 1}, {main: 6}}, + []byte("foo"), []byte("foo1"), 6, 0, []revision{{main: 6}}, 1, }, - // range keys, return first two members { - []byte("foo"), []byte("foo2"), []revision{{main: 1}, {main: 2}, {main: 5}, {main: 6}}, + []byte("foo"), []byte("foo2"), 6, 0, []revision{{main: 6}, {main: 5}}, 2, }, - // range keys, return all members { - []byte("foo"), []byte("fop"), allRevs, + []byte("foo"), []byte("fop"), 6, 0, []revision{{main: 6}, {main: 5}, {main: 4}}, 3, }, - // range keys, return last two members { - []byte("foo1"), []byte("fop"), []revision{{main: 2}, {main: 3}, {main: 4}, {main: 5}}, + []byte("foo1"), []byte("fop"), 6, 0, []revision{{main: 5}, {main: 4}}, 2, }, - // range keys, return last member { - []byte("foo2"), []byte("fop"), []revision{{main: 3}, {main: 4}}, + []byte("foo2"), []byte("fop"), 6, 0, []revision{{main: 4}}, 1, }, - // range keys, return nothing { - []byte("foo3"), []byte("fop"), nil, + []byte("foo3"), []byte("fop"), 6, 0, nil, 0, + }, + // fixed range keys, various atRev, unlimited + { + []byte("foo1"), []byte("fop"), 1, 0, nil, 0, + }, + { + []byte("foo1"), []byte("fop"), 2, 0, []revision{{main: 2}}, 1, + }, + { + []byte("foo1"), []byte("fop"), 3, 0, []revision{{main: 2}, {main: 3}}, 2, + }, + { + []byte("foo1"), []byte("fop"), 4, 0, []revision{{main: 2}, {main: 4}}, 2, + }, + { + []byte("foo1"), []byte("fop"), 5, 0, []revision{{main: 5}, {main: 4}}, 2, + }, + { + []byte("foo1"), []byte("fop"), 6, 0, []revision{{main: 5}, {main: 4}}, 2, + }, + // fixed range keys, fixed atRev, various limit + { + []byte("foo"), []byte("fop"), 6, 1, []revision{{main: 6}}, 3, + }, + { + []byte("foo"), []byte("fop"), 6, 2, []revision{{main: 6}, {main: 5}}, 3, + }, + { + []byte("foo"), []byte("fop"), 6, 3, []revision{{main: 6}, {main: 5}, {main: 4}}, 3, + }, + { + []byte("foo"), []byte("fop"), 3, 1, []revision{{main: 1}}, 3, + }, + { + []byte("foo"), []byte("fop"), 3, 2, []revision{{main: 1}, {main: 2}}, 3, + }, + { + []byte("foo"), []byte("fop"), 3, 3, []revision{{main: 1}, {main: 2}, {main: 3}}, 3, }, } for i, tt := range tests { - revs := ti.RangeSince(tt.key, tt.end, atRev) + revs, _ := ti.Revisions(tt.key, tt.end, tt.atRev, tt.limit) if !reflect.DeepEqual(revs, tt.wrevs) { - t.Errorf("#%d: revs = %+v, want %+v", i, revs, tt.wrevs) + t.Errorf("#%d limit %d: revs = %+v, want %+v", i, tt.limit, revs, tt.wrevs) + } + count := ti.CountRevisions(tt.key, tt.end, tt.atRev) + if count != tt.wcounts { + t.Errorf("#%d: count = %d, want %v", i, count, tt.wcounts) } } }