|
|
@@ -7,23 +7,22 @@ import (
|
|
|
|
|
|
func TestKeyIndexGet(t *testing.T) {
|
|
|
// key: "foo"
|
|
|
- // index: 12
|
|
|
+ // rev: 12
|
|
|
// generations:
|
|
|
// {empty}
|
|
|
// {8[1], 10[2], 12(t)[3]}
|
|
|
// {4[2], 6(t)[3]}
|
|
|
ki := newTestKeyIndex()
|
|
|
- ki.compact(4, make(map[uint64]struct{}))
|
|
|
+ ki.compact(4, make(map[reversion]struct{}))
|
|
|
|
|
|
tests := []struct {
|
|
|
- index uint64
|
|
|
+ rev int64
|
|
|
|
|
|
- windex uint64
|
|
|
- werr error
|
|
|
+ wrev int64
|
|
|
+ werr error
|
|
|
}{
|
|
|
- // expected not exist on an index that is greater than the last tombstone
|
|
|
- {13, 0, ErrIndexNotFound},
|
|
|
- {13, 0, ErrIndexNotFound},
|
|
|
+ {13, 12, nil},
|
|
|
+ {13, 12, nil},
|
|
|
|
|
|
// get on generation 2
|
|
|
{12, 12, nil},
|
|
|
@@ -31,7 +30,7 @@ func TestKeyIndexGet(t *testing.T) {
|
|
|
{10, 10, nil},
|
|
|
{9, 8, nil},
|
|
|
{8, 8, nil},
|
|
|
- {7, 0, ErrIndexNotFound},
|
|
|
+ {7, 6, nil},
|
|
|
|
|
|
// get on generation 1
|
|
|
{6, 6, nil},
|
|
|
@@ -40,35 +39,35 @@ func TestKeyIndexGet(t *testing.T) {
|
|
|
}
|
|
|
|
|
|
for i, tt := range tests {
|
|
|
- index, err := ki.get(tt.index)
|
|
|
+ rev, err := ki.get(tt.rev)
|
|
|
if err != tt.werr {
|
|
|
t.Errorf("#%d: err = %v, want %v", i, err, tt.werr)
|
|
|
}
|
|
|
- if index != tt.windex {
|
|
|
- t.Errorf("#%d: index = %d, want %d", i, index, tt.index)
|
|
|
+ if rev.main != tt.wrev {
|
|
|
+ t.Errorf("#%d: rev = %d, want %d", i, rev.main, tt.rev)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
func TestKeyIndexPut(t *testing.T) {
|
|
|
ki := &keyIndex{key: []byte("foo")}
|
|
|
- ki.put(5)
|
|
|
+ ki.put(5, 0)
|
|
|
|
|
|
wki := &keyIndex{
|
|
|
key: []byte("foo"),
|
|
|
- index: 5,
|
|
|
- generations: []generation{{ver: 1, cont: []uint64{5}}},
|
|
|
+ rev: 5,
|
|
|
+ generations: []generation{{ver: 1, revs: []reversion{{main: 5}}}},
|
|
|
}
|
|
|
if !reflect.DeepEqual(ki, wki) {
|
|
|
t.Errorf("ki = %+v, want %+v", ki, wki)
|
|
|
}
|
|
|
|
|
|
- ki.put(7)
|
|
|
+ ki.put(7, 0)
|
|
|
|
|
|
wki = &keyIndex{
|
|
|
key: []byte("foo"),
|
|
|
- index: 7,
|
|
|
- generations: []generation{{ver: 2, cont: []uint64{5, 7}}},
|
|
|
+ rev: 7,
|
|
|
+ generations: []generation{{ver: 2, revs: []reversion{{main: 5}, {main: 7}}}},
|
|
|
}
|
|
|
if !reflect.DeepEqual(ki, wki) {
|
|
|
t.Errorf("ki = %+v, want %+v", ki, wki)
|
|
|
@@ -77,27 +76,31 @@ func TestKeyIndexPut(t *testing.T) {
|
|
|
|
|
|
func TestKeyIndexTombstone(t *testing.T) {
|
|
|
ki := &keyIndex{key: []byte("foo")}
|
|
|
- ki.put(5)
|
|
|
+ ki.put(5, 0)
|
|
|
|
|
|
- ki.tombstone(7)
|
|
|
+ ki.tombstone(7, 0)
|
|
|
|
|
|
wki := &keyIndex{
|
|
|
key: []byte("foo"),
|
|
|
- index: 7,
|
|
|
- generations: []generation{{ver: 2, cont: []uint64{5, 7}}, {}},
|
|
|
+ rev: 7,
|
|
|
+ generations: []generation{{ver: 2, revs: []reversion{{main: 5}, {main: 7}}}, {}},
|
|
|
}
|
|
|
if !reflect.DeepEqual(ki, wki) {
|
|
|
t.Errorf("ki = %+v, want %+v", ki, wki)
|
|
|
}
|
|
|
|
|
|
- ki.put(8)
|
|
|
- ki.put(9)
|
|
|
- ki.tombstone(15)
|
|
|
+ ki.put(8, 0)
|
|
|
+ ki.put(9, 0)
|
|
|
+ ki.tombstone(15, 0)
|
|
|
|
|
|
wki = &keyIndex{
|
|
|
- key: []byte("foo"),
|
|
|
- index: 15,
|
|
|
- generations: []generation{{ver: 2, cont: []uint64{5, 7}}, {ver: 3, cont: []uint64{8, 9, 15}}, {}},
|
|
|
+ key: []byte("foo"),
|
|
|
+ rev: 15,
|
|
|
+ generations: []generation{
|
|
|
+ {ver: 2, revs: []reversion{{main: 5}, {main: 7}}},
|
|
|
+ {ver: 3, revs: []reversion{{main: 8}, {main: 9}, {main: 15}}},
|
|
|
+ {},
|
|
|
+ },
|
|
|
}
|
|
|
if !reflect.DeepEqual(ki, wki) {
|
|
|
t.Errorf("ki = %+v, want %+v", ki, wki)
|
|
|
@@ -106,221 +109,192 @@ func TestKeyIndexTombstone(t *testing.T) {
|
|
|
|
|
|
func TestKeyIndexCompact(t *testing.T) {
|
|
|
tests := []struct {
|
|
|
- compact uint64
|
|
|
+ compact int64
|
|
|
|
|
|
wki *keyIndex
|
|
|
- wam map[uint64]struct{}
|
|
|
+ wam map[reversion]struct{}
|
|
|
}{
|
|
|
{
|
|
|
1,
|
|
|
&keyIndex{
|
|
|
- key: []byte("foo"),
|
|
|
- index: 12,
|
|
|
+ key: []byte("foo"),
|
|
|
+ rev: 12,
|
|
|
generations: []generation{
|
|
|
- {ver: 3, cont: []uint64{2, 4, 6}},
|
|
|
- {ver: 3, cont: []uint64{8, 10, 12}},
|
|
|
+ {ver: 3, revs: []reversion{{main: 2}, {main: 4}, {main: 6}}},
|
|
|
+ {ver: 3, revs: []reversion{{main: 8}, {main: 10}, {main: 12}}},
|
|
|
{},
|
|
|
},
|
|
|
},
|
|
|
- map[uint64]struct{}{
|
|
|
- 2: struct{}{}, 4: struct{}{}, 6: struct{}{},
|
|
|
- 8: struct{}{}, 10: struct{}{}, 12: struct{}{},
|
|
|
- },
|
|
|
+ map[reversion]struct{}{},
|
|
|
},
|
|
|
{
|
|
|
2,
|
|
|
&keyIndex{
|
|
|
- key: []byte("foo"),
|
|
|
- index: 12,
|
|
|
+ key: []byte("foo"),
|
|
|
+ rev: 12,
|
|
|
generations: []generation{
|
|
|
- {ver: 3, cont: []uint64{2, 4, 6}},
|
|
|
- {ver: 3, cont: []uint64{8, 10, 12}},
|
|
|
+ {ver: 3, revs: []reversion{{main: 2}, {main: 4}, {main: 6}}},
|
|
|
+ {ver: 3, revs: []reversion{{main: 8}, {main: 10}, {main: 12}}},
|
|
|
{},
|
|
|
},
|
|
|
},
|
|
|
- map[uint64]struct{}{
|
|
|
- 2: struct{}{}, 4: struct{}{}, 6: struct{}{},
|
|
|
- 8: struct{}{}, 10: struct{}{}, 12: struct{}{},
|
|
|
+ map[reversion]struct{}{
|
|
|
+ reversion{main: 2}: struct{}{},
|
|
|
},
|
|
|
},
|
|
|
{
|
|
|
3,
|
|
|
&keyIndex{
|
|
|
- key: []byte("foo"),
|
|
|
- index: 12,
|
|
|
+ key: []byte("foo"),
|
|
|
+ rev: 12,
|
|
|
generations: []generation{
|
|
|
- {ver: 3, cont: []uint64{2, 4, 6}},
|
|
|
- {ver: 3, cont: []uint64{8, 10, 12}},
|
|
|
+ {ver: 3, revs: []reversion{{main: 2}, {main: 4}, {main: 6}}},
|
|
|
+ {ver: 3, revs: []reversion{{main: 8}, {main: 10}, {main: 12}}},
|
|
|
{},
|
|
|
},
|
|
|
},
|
|
|
- map[uint64]struct{}{
|
|
|
- 2: struct{}{}, 4: struct{}{}, 6: struct{}{},
|
|
|
- 8: struct{}{}, 10: struct{}{}, 12: struct{}{},
|
|
|
+ map[reversion]struct{}{
|
|
|
+ reversion{main: 2}: struct{}{},
|
|
|
},
|
|
|
},
|
|
|
{
|
|
|
4,
|
|
|
&keyIndex{
|
|
|
- key: []byte("foo"),
|
|
|
- index: 12,
|
|
|
+ key: []byte("foo"),
|
|
|
+ rev: 12,
|
|
|
generations: []generation{
|
|
|
- {ver: 3, cont: []uint64{4, 6}},
|
|
|
- {ver: 3, cont: []uint64{8, 10, 12}},
|
|
|
+ {ver: 3, revs: []reversion{{main: 4}, {main: 6}}},
|
|
|
+ {ver: 3, revs: []reversion{{main: 8}, {main: 10}, {main: 12}}},
|
|
|
{},
|
|
|
},
|
|
|
},
|
|
|
- map[uint64]struct{}{
|
|
|
- 4: struct{}{}, 6: struct{}{},
|
|
|
- 8: struct{}{}, 10: struct{}{}, 12: struct{}{},
|
|
|
+ map[reversion]struct{}{
|
|
|
+ reversion{main: 4}: struct{}{},
|
|
|
},
|
|
|
},
|
|
|
{
|
|
|
5,
|
|
|
&keyIndex{
|
|
|
- key: []byte("foo"),
|
|
|
- index: 12,
|
|
|
+ key: []byte("foo"),
|
|
|
+ rev: 12,
|
|
|
generations: []generation{
|
|
|
- {ver: 3, cont: []uint64{4, 6}},
|
|
|
- {ver: 3, cont: []uint64{8, 10, 12}},
|
|
|
+ {ver: 3, revs: []reversion{{main: 4}, {main: 6}}},
|
|
|
+ {ver: 3, revs: []reversion{{main: 8}, {main: 10}, {main: 12}}},
|
|
|
{},
|
|
|
},
|
|
|
},
|
|
|
- map[uint64]struct{}{
|
|
|
- 4: struct{}{}, 6: struct{}{},
|
|
|
- 8: struct{}{}, 10: struct{}{}, 12: struct{}{},
|
|
|
+ map[reversion]struct{}{
|
|
|
+ reversion{main: 4}: struct{}{},
|
|
|
},
|
|
|
},
|
|
|
{
|
|
|
6,
|
|
|
&keyIndex{
|
|
|
- key: []byte("foo"),
|
|
|
- index: 12,
|
|
|
+ key: []byte("foo"),
|
|
|
+ rev: 12,
|
|
|
generations: []generation{
|
|
|
- {ver: 3, cont: []uint64{6}},
|
|
|
- {ver: 3, cont: []uint64{8, 10, 12}},
|
|
|
+ {ver: 3, revs: []reversion{{main: 8}, {main: 10}, {main: 12}}},
|
|
|
{},
|
|
|
},
|
|
|
},
|
|
|
- map[uint64]struct{}{
|
|
|
- 6: struct{}{},
|
|
|
- 8: struct{}{}, 10: struct{}{}, 12: struct{}{},
|
|
|
- },
|
|
|
+ map[reversion]struct{}{},
|
|
|
},
|
|
|
{
|
|
|
7,
|
|
|
&keyIndex{
|
|
|
- key: []byte("foo"),
|
|
|
- index: 12,
|
|
|
+ key: []byte("foo"),
|
|
|
+ rev: 12,
|
|
|
generations: []generation{
|
|
|
- {ver: 3, cont: []uint64{8, 10, 12}},
|
|
|
+ {ver: 3, revs: []reversion{{main: 8}, {main: 10}, {main: 12}}},
|
|
|
{},
|
|
|
},
|
|
|
},
|
|
|
- map[uint64]struct{}{
|
|
|
- 8: struct{}{}, 10: struct{}{}, 12: struct{}{},
|
|
|
- },
|
|
|
+ map[reversion]struct{}{},
|
|
|
},
|
|
|
{
|
|
|
8,
|
|
|
&keyIndex{
|
|
|
- key: []byte("foo"),
|
|
|
- index: 12,
|
|
|
+ key: []byte("foo"),
|
|
|
+ rev: 12,
|
|
|
generations: []generation{
|
|
|
- {ver: 3, cont: []uint64{8, 10, 12}},
|
|
|
+ {ver: 3, revs: []reversion{{main: 8}, {main: 10}, {main: 12}}},
|
|
|
{},
|
|
|
},
|
|
|
},
|
|
|
- map[uint64]struct{}{
|
|
|
- 8: struct{}{}, 10: struct{}{}, 12: struct{}{},
|
|
|
+ map[reversion]struct{}{
|
|
|
+ reversion{main: 8}: struct{}{},
|
|
|
},
|
|
|
},
|
|
|
{
|
|
|
9,
|
|
|
&keyIndex{
|
|
|
- key: []byte("foo"),
|
|
|
- index: 12,
|
|
|
+ key: []byte("foo"),
|
|
|
+ rev: 12,
|
|
|
generations: []generation{
|
|
|
- {ver: 3, cont: []uint64{8, 10, 12}},
|
|
|
+ {ver: 3, revs: []reversion{{main: 8}, {main: 10}, {main: 12}}},
|
|
|
{},
|
|
|
},
|
|
|
},
|
|
|
- map[uint64]struct{}{
|
|
|
- 8: struct{}{}, 10: struct{}{}, 12: struct{}{},
|
|
|
+ map[reversion]struct{}{
|
|
|
+ reversion{main: 8}: struct{}{},
|
|
|
},
|
|
|
},
|
|
|
{
|
|
|
10,
|
|
|
&keyIndex{
|
|
|
- key: []byte("foo"),
|
|
|
- index: 12,
|
|
|
+ key: []byte("foo"),
|
|
|
+ rev: 12,
|
|
|
generations: []generation{
|
|
|
- {ver: 3, cont: []uint64{10, 12}},
|
|
|
+ {ver: 3, revs: []reversion{{main: 10}, {main: 12}}},
|
|
|
{},
|
|
|
},
|
|
|
},
|
|
|
- map[uint64]struct{}{
|
|
|
- 10: struct{}{}, 12: struct{}{},
|
|
|
+ map[reversion]struct{}{
|
|
|
+ reversion{main: 10}: struct{}{},
|
|
|
},
|
|
|
},
|
|
|
{
|
|
|
11,
|
|
|
&keyIndex{
|
|
|
- key: []byte("foo"),
|
|
|
- index: 12,
|
|
|
+ key: []byte("foo"),
|
|
|
+ rev: 12,
|
|
|
generations: []generation{
|
|
|
- {ver: 3, cont: []uint64{10, 12}},
|
|
|
+ {ver: 3, revs: []reversion{{main: 10}, {main: 12}}},
|
|
|
{},
|
|
|
},
|
|
|
},
|
|
|
- map[uint64]struct{}{
|
|
|
- 10: struct{}{}, 12: struct{}{},
|
|
|
+ map[reversion]struct{}{
|
|
|
+ reversion{main: 10}: struct{}{},
|
|
|
},
|
|
|
},
|
|
|
{
|
|
|
12,
|
|
|
&keyIndex{
|
|
|
- key: []byte("foo"),
|
|
|
- index: 12,
|
|
|
- generations: []generation{
|
|
|
- {ver: 3, cont: []uint64{12}},
|
|
|
- {},
|
|
|
- },
|
|
|
- },
|
|
|
- map[uint64]struct{}{
|
|
|
- 12: struct{}{},
|
|
|
- },
|
|
|
- },
|
|
|
- {
|
|
|
- 13,
|
|
|
- &keyIndex{
|
|
|
- key: []byte("foo"),
|
|
|
- index: 12,
|
|
|
- generations: []generation{
|
|
|
- {},
|
|
|
- },
|
|
|
+ key: []byte("foo"),
|
|
|
+ rev: 12,
|
|
|
+ generations: []generation{{}},
|
|
|
},
|
|
|
- map[uint64]struct{}{},
|
|
|
+ map[reversion]struct{}{},
|
|
|
},
|
|
|
}
|
|
|
|
|
|
// Continous Compaction
|
|
|
ki := newTestKeyIndex()
|
|
|
for i, tt := range tests {
|
|
|
- am := make(map[uint64]struct{})
|
|
|
+ am := make(map[reversion]struct{})
|
|
|
ki.compact(tt.compact, am)
|
|
|
if !reflect.DeepEqual(ki, tt.wki) {
|
|
|
t.Errorf("#%d: ki = %+v, want %+v", i, ki, tt.wki)
|
|
|
}
|
|
|
if !reflect.DeepEqual(am, tt.wam) {
|
|
|
- t.Errorf("#%d: am = %+v, want %+v", am, tt.wam)
|
|
|
+ t.Errorf("#%d: am = %+v, want %+v", i, am, tt.wam)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// Jump Compaction
|
|
|
for i, tt := range tests {
|
|
|
if (i%2 == 0 && i < 6) && (i%2 == 1 && i > 6) {
|
|
|
- am := make(map[uint64]struct{})
|
|
|
+ am := make(map[reversion]struct{})
|
|
|
ki.compact(tt.compact, am)
|
|
|
if !reflect.DeepEqual(ki, tt.wki) {
|
|
|
t.Errorf("#%d: ki = %+v, want %+v", i, ki, tt.wki)
|
|
|
@@ -334,31 +308,31 @@ func TestKeyIndexCompact(t *testing.T) {
|
|
|
// OnceCompaction
|
|
|
for i, tt := range tests {
|
|
|
ki := newTestKeyIndex()
|
|
|
- am := make(map[uint64]struct{})
|
|
|
+ am := make(map[reversion]struct{})
|
|
|
ki.compact(tt.compact, am)
|
|
|
if !reflect.DeepEqual(ki, tt.wki) {
|
|
|
t.Errorf("#%d: ki = %+v, want %+v", i, ki, tt.wki)
|
|
|
}
|
|
|
if !reflect.DeepEqual(am, tt.wam) {
|
|
|
- t.Errorf("#%d: am = %+v, want %+v", am, tt.wam)
|
|
|
+ t.Errorf("#%d: am = %+v, want %+v", i, am, tt.wam)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
func newTestKeyIndex() *keyIndex {
|
|
|
// key: "foo"
|
|
|
- // index: 12
|
|
|
+ // rev: 12
|
|
|
// generations:
|
|
|
// {empty}
|
|
|
// {8[1], 10[2], 12(t)[3]}
|
|
|
// {2[1], 4[2], 6(t)[3]}
|
|
|
|
|
|
ki := &keyIndex{key: []byte("foo")}
|
|
|
- ki.put(2)
|
|
|
- ki.put(4)
|
|
|
- ki.tombstone(6)
|
|
|
- ki.put(8)
|
|
|
- ki.put(10)
|
|
|
- ki.tombstone(12)
|
|
|
+ ki.put(2, 0)
|
|
|
+ ki.put(4, 0)
|
|
|
+ ki.tombstone(6, 0)
|
|
|
+ ki.put(8, 0)
|
|
|
+ ki.put(10, 0)
|
|
|
+ ki.tombstone(12, 0)
|
|
|
return ki
|
|
|
}
|