Browse Source

mvcc: add tests for Keep

fanmin shi 8 years ago
parent
commit
4c2c5b0084
4 changed files with 65 additions and 11 deletions
  1. 11 5
      mvcc/index_test.go
  2. 2 2
      mvcc/key_index.go
  3. 48 4
      mvcc/key_index_test.go
  4. 4 0
      mvcc/kvstore_test.go

+ 11 - 5
mvcc/index_test.go

@@ -193,7 +193,7 @@ func TestIndexRangeSince(t *testing.T) {
 	}
 	}
 }
 }
 
 
-func TestIndexCompact(t *testing.T) {
+func TestIndexCompactAndKeep(t *testing.T) {
 	maxRev := int64(20)
 	maxRev := int64(20)
 	tests := []struct {
 	tests := []struct {
 		key     []byte
 		key     []byte
@@ -215,7 +215,7 @@ func TestIndexCompact(t *testing.T) {
 		{[]byte("foo1"), false, revision{10, 1}, revision{10, 1}, 1},
 		{[]byte("foo1"), false, revision{10, 1}, revision{10, 1}, 1},
 	}
 	}
 
 
-	// Continuous Compact
+	// Continuous Compact and Keep
 	ti := newTreeIndex()
 	ti := newTreeIndex()
 	for _, tt := range tests {
 	for _, tt := range tests {
 		if tt.remove {
 		if tt.remove {
@@ -226,7 +226,10 @@ func TestIndexCompact(t *testing.T) {
 	}
 	}
 	for i := int64(1); i < maxRev; i++ {
 	for i := int64(1); i < maxRev; i++ {
 		am := ti.Compact(i)
 		am := ti.Compact(i)
-
+		keep := ti.Keep(i)
+		if !(reflect.DeepEqual(am, keep)) {
+			t.Errorf("#%d: compact keep %v != Keep keep %v", i, am, keep)
+		}
 		wti := &treeIndex{tree: btree.New(32)}
 		wti := &treeIndex{tree: btree.New(32)}
 		for _, tt := range tests {
 		for _, tt := range tests {
 			if _, ok := am[tt.rev]; ok || tt.rev.GreaterThan(revision{main: i}) {
 			if _, ok := am[tt.rev]; ok || tt.rev.GreaterThan(revision{main: i}) {
@@ -242,7 +245,7 @@ func TestIndexCompact(t *testing.T) {
 		}
 		}
 	}
 	}
 
 
-	// Once Compact
+	// Once Compact and Keep
 	for i := int64(1); i < maxRev; i++ {
 	for i := int64(1); i < maxRev; i++ {
 		ti := newTreeIndex()
 		ti := newTreeIndex()
 		for _, tt := range tests {
 		for _, tt := range tests {
@@ -253,7 +256,10 @@ func TestIndexCompact(t *testing.T) {
 			}
 			}
 		}
 		}
 		am := ti.Compact(i)
 		am := ti.Compact(i)
-
+		keep := ti.Keep(i)
+		if !(reflect.DeepEqual(am, keep)) {
+			t.Errorf("#%d: compact keep %v != Keep keep %v", i, am, keep)
+		}
 		wti := &treeIndex{tree: btree.New(32)}
 		wti := &treeIndex{tree: btree.New(32)}
 		for _, tt := range tests {
 		for _, tt := range tests {
 			if _, ok := am[tt.rev]; ok || tt.rev.GreaterThan(revision{main: i}) {
 			if _, ok := am[tt.rev]; ok || tt.rev.GreaterThan(revision{main: i}) {

+ 2 - 2
mvcc/key_index.go

@@ -189,7 +189,7 @@ func (ki *keyIndex) compact(atRev int64, available map[revision]struct{}) {
 
 
 	genIdx, revIndex := ki.doCompact(atRev, available)
 	genIdx, revIndex := ki.doCompact(atRev, available)
 
 
-	g := ki.generations[genIdx]
+	g := &ki.generations[genIdx]
 	if !g.isEmpty() {
 	if !g.isEmpty() {
 		// remove the previous contents.
 		// remove the previous contents.
 		if revIndex != -1 {
 		if revIndex != -1 {
@@ -213,7 +213,7 @@ func (ki *keyIndex) keep(atRev int64, available map[revision]struct{}) {
 	}
 	}
 
 
 	genIdx, revIndex := ki.doCompact(atRev, available)
 	genIdx, revIndex := ki.doCompact(atRev, available)
-	g := ki.generations[genIdx]
+	g := &ki.generations[genIdx]
 	if !g.isEmpty() {
 	if !g.isEmpty() {
 		// remove any tombstone
 		// remove any tombstone
 		if revIndex == len(g.revs)-1 && genIdx != len(ki.generations)-1 {
 		if revIndex == len(g.revs)-1 && genIdx != len(ki.generations)-1 {

+ 48 - 4
mvcc/key_index_test.go

@@ -205,7 +205,7 @@ func TestKeyIndexTombstone(t *testing.T) {
 	}
 	}
 }
 }
 
 
-func TestKeyIndexCompact(t *testing.T) {
+func TestKeyIndexCompactAndKeep(t *testing.T) {
 	tests := []struct {
 	tests := []struct {
 		compact int64
 		compact int64
 
 
@@ -441,10 +441,19 @@ func TestKeyIndexCompact(t *testing.T) {
 		},
 		},
 	}
 	}
 
 
-	// Continuous Compaction
+	// Continuous Compaction and finding Keep
 	ki := newTestKeyIndex()
 	ki := newTestKeyIndex()
 	for i, tt := range tests {
 	for i, tt := range tests {
 		am := make(map[revision]struct{})
 		am := make(map[revision]struct{})
+		kiclone := cloneKeyIndex(ki)
+		ki.keep(tt.compact, am)
+		if !reflect.DeepEqual(ki, kiclone) {
+			t.Errorf("#%d: ki = %+v, want %+v", i, ki, kiclone)
+		}
+		if !reflect.DeepEqual(am, tt.wam) {
+			t.Errorf("#%d: am = %+v, want %+v", i, am, tt.wam)
+		}
+		am = make(map[revision]struct{})
 		ki.compact(tt.compact, am)
 		ki.compact(tt.compact, am)
 		if !reflect.DeepEqual(ki, tt.wki) {
 		if !reflect.DeepEqual(ki, tt.wki) {
 			t.Errorf("#%d: ki = %+v, want %+v", i, ki, tt.wki)
 			t.Errorf("#%d: ki = %+v, want %+v", i, ki, tt.wki)
@@ -454,11 +463,20 @@ func TestKeyIndexCompact(t *testing.T) {
 		}
 		}
 	}
 	}
 
 
-	// Jump Compaction
+	// Jump Compaction and finding Keep
 	ki = newTestKeyIndex()
 	ki = newTestKeyIndex()
 	for i, tt := range tests {
 	for i, tt := range tests {
 		if (i%2 == 0 && i < 6) || (i%2 == 1 && i > 6) {
 		if (i%2 == 0 && i < 6) || (i%2 == 1 && i > 6) {
 			am := make(map[revision]struct{})
 			am := make(map[revision]struct{})
+			kiclone := cloneKeyIndex(ki)
+			ki.keep(tt.compact, am)
+			if !reflect.DeepEqual(ki, kiclone) {
+				t.Errorf("#%d: ki = %+v, want %+v", i, ki, kiclone)
+			}
+			if !reflect.DeepEqual(am, tt.wam) {
+				t.Errorf("#%d: am = %+v, want %+v", i, am, tt.wam)
+			}
+			am = make(map[revision]struct{})
 			ki.compact(tt.compact, am)
 			ki.compact(tt.compact, am)
 			if !reflect.DeepEqual(ki, tt.wki) {
 			if !reflect.DeepEqual(ki, tt.wki) {
 				t.Errorf("#%d: ki = %+v, want %+v", i, ki, tt.wki)
 				t.Errorf("#%d: ki = %+v, want %+v", i, ki, tt.wki)
@@ -469,10 +487,19 @@ func TestKeyIndexCompact(t *testing.T) {
 		}
 		}
 	}
 	}
 
 
-	// Once Compaction
+	kiClone := newTestKeyIndex()
+	// Once Compaction and finding Keep
 	for i, tt := range tests {
 	for i, tt := range tests {
 		ki := newTestKeyIndex()
 		ki := newTestKeyIndex()
 		am := make(map[revision]struct{})
 		am := make(map[revision]struct{})
+		ki.keep(tt.compact, am)
+		if !reflect.DeepEqual(ki, kiClone) {
+			t.Errorf("#%d: ki = %+v, want %+v", i, ki, kiClone)
+		}
+		if !reflect.DeepEqual(am, tt.wam) {
+			t.Errorf("#%d: am = %+v, want %+v", i, am, tt.wam)
+		}
+		am = make(map[revision]struct{})
 		ki.compact(tt.compact, am)
 		ki.compact(tt.compact, am)
 		if !reflect.DeepEqual(ki, tt.wki) {
 		if !reflect.DeepEqual(ki, tt.wki) {
 			t.Errorf("#%d: ki = %+v, want %+v", i, ki, tt.wki)
 			t.Errorf("#%d: ki = %+v, want %+v", i, ki, tt.wki)
@@ -483,6 +510,23 @@ func TestKeyIndexCompact(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func cloneKeyIndex(ki *keyIndex) *keyIndex {
+	generations := make([]generation, len(ki.generations))
+	for i, gen := range ki.generations {
+		generations[i] = *cloneGeneration(&gen)
+	}
+	return &keyIndex{ki.key, ki.modified, generations}
+}
+
+func cloneGeneration(g *generation) *generation {
+	if g.revs == nil {
+		return &generation{g.ver, g.created, nil}
+	}
+	tmp := make([]revision, len(g.revs))
+	copy(tmp, g.revs)
+	return &generation{g.ver, g.created, tmp}
+}
+
 // test that compact on version that higher than last modified version works well
 // test that compact on version that higher than last modified version works well
 func TestKeyIndexCompactOnFurtherRev(t *testing.T) {
 func TestKeyIndexCompactOnFurtherRev(t *testing.T) {
 	ki := &keyIndex{key: []byte("foo")}
 	ki := &keyIndex{key: []byte("foo")}

+ 4 - 0
mvcc/kvstore_test.go

@@ -767,6 +767,10 @@ func (i *fakeIndex) Compact(rev int64) map[revision]struct{} {
 	i.Recorder.Record(testutil.Action{Name: "compact", Params: []interface{}{rev}})
 	i.Recorder.Record(testutil.Action{Name: "compact", Params: []interface{}{rev}})
 	return <-i.indexCompactRespc
 	return <-i.indexCompactRespc
 }
 }
+func (i *fakeIndex) Keep(rev int64) map[revision]struct{} {
+	i.Recorder.Record(testutil.Action{Name: "keep", Params: []interface{}{rev}})
+	return <-i.indexCompactRespc
+}
 func (i *fakeIndex) Equal(b index) bool { return false }
 func (i *fakeIndex) Equal(b index) bool { return false }
 
 
 func (i *fakeIndex) Insert(ki *keyIndex) {
 func (i *fakeIndex) Insert(ki *keyIndex) {