Browse Source

storage: keyIndex.get returns err when key is tombstoned

Before this commit, it will return wrong create index, mod index.

It lets findGeneration return error when rev is at the gap of two
generations. This leads to the change of compact() code.
Yicheng Qin 10 years ago
parent
commit
62f7481b19
3 changed files with 21 additions and 22 deletions
  1. 2 6
      storage/index_test.go
  2. 14 11
      storage/key_index.go
  3. 5 5
      storage/key_index_test.go

+ 2 - 6
storage/index_test.go

@@ -91,14 +91,10 @@ func TestIndexTombstone(t *testing.T) {
 	if err != nil {
 	if err != nil {
 		t.Errorf("tombstone error = %v, want nil", err)
 		t.Errorf("tombstone error = %v, want nil", err)
 	}
 	}
-	rev, _, _, err := index.Get([]byte("foo"), 7)
-	if err != nil {
+	_, _, _, err = index.Get([]byte("foo"), 7)
+	if err != ErrRevisionNotFound {
 		t.Errorf("get error = %v, want nil", err)
 		t.Errorf("get error = %v, want nil", err)
 	}
 	}
-	w := revision{main: 7}
-	if !reflect.DeepEqual(rev, w) {
-		t.Errorf("get revision = %+v, want %+v", rev, w)
-	}
 }
 }
 
 
 func TestContinuousCompact(t *testing.T) {
 func TestContinuousCompact(t *testing.T) {

+ 14 - 11
storage/key_index.go

@@ -144,18 +144,14 @@ func (ki *keyIndex) compact(atRev int64, available map[revision]struct{}) {
 		return true
 		return true
 	}
 	}
 
 
-	g := ki.findGeneration(atRev)
-	if g == nil {
-		return
-	}
-
-	i := 0
-	for i <= len(ki.generations)-1 {
-		wg := &ki.generations[i]
-		if wg == g {
+	i, g := 0, &ki.generations[0]
+	// find first generation includes atRev or created after atRev
+	for i < len(ki.generations)-1 {
+		if tomb := g.revs[len(g.revs)-1].main; tomb > atRev {
 			break
 			break
 		}
 		}
 		i++
 		i++
+		g = &ki.generations[i]
 	}
 	}
 
 
 	if !g.isEmpty() {
 	if !g.isEmpty() {
@@ -180,9 +176,11 @@ func (ki *keyIndex) isEmpty() bool {
 }
 }
 
 
 // findGeneartion finds out the generation of the keyIndex that the
 // findGeneartion finds out the generation of the keyIndex that the
-// given index belongs to.
+// given rev belongs to. If the given rev is at the gap of two generations,
+// which means that the key does not exist at the given rev, it returns nil.
 func (ki *keyIndex) findGeneration(rev int64) *generation {
 func (ki *keyIndex) findGeneration(rev int64) *generation {
-	cg := len(ki.generations) - 1
+	lastg := len(ki.generations) - 1
+	cg := lastg
 
 
 	for cg >= 0 {
 	for cg >= 0 {
 		if len(ki.generations[cg].revs) == 0 {
 		if len(ki.generations[cg].revs) == 0 {
@@ -190,6 +188,11 @@ func (ki *keyIndex) findGeneration(rev int64) *generation {
 			continue
 			continue
 		}
 		}
 		g := ki.generations[cg]
 		g := ki.generations[cg]
+		if cg != lastg {
+			if tomb := g.revs[len(g.revs)-1].main; tomb <= rev {
+				return nil
+			}
+		}
 		if g.revs[0].main <= rev {
 		if g.revs[0].main <= rev {
 			return &ki.generations[cg]
 			return &ki.generations[cg]
 		}
 		}

+ 5 - 5
storage/key_index_test.go

@@ -21,19 +21,19 @@ func TestKeyIndexGet(t *testing.T) {
 		wrev int64
 		wrev int64
 		werr error
 		werr error
 	}{
 	}{
-		{13, 12, nil},
-		{13, 12, nil},
+		{13, 0, ErrRevisionNotFound},
+		{13, 0, ErrRevisionNotFound},
 
 
 		// get on generation 2
 		// get on generation 2
-		{12, 12, nil},
+		{12, 0, ErrRevisionNotFound},
 		{11, 10, nil},
 		{11, 10, nil},
 		{10, 10, nil},
 		{10, 10, nil},
 		{9, 8, nil},
 		{9, 8, nil},
 		{8, 8, nil},
 		{8, 8, nil},
-		{7, 6, nil},
+		{7, 0, ErrRevisionNotFound},
 
 
 		// get on generation 1
 		// get on generation 1
-		{6, 6, nil},
+		{6, 0, ErrRevisionNotFound},
 		{5, 4, nil},
 		{5, 4, nil},
 		{4, 4, nil},
 		{4, 4, nil},
 	}
 	}