Merge pull request #450 from mschoch/bug449
fix logic in Advance() of UpsideDownCouchDocIDReader
This commit is contained in:
commit
1f79f65b6a
@ -239,12 +239,16 @@ func (r *UpsideDownCouchDocIDReader) Next() (index.IndexInternalID, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *UpsideDownCouchDocIDReader) Advance(docID index.IndexInternalID) (index.IndexInternalID, error) {
|
func (r *UpsideDownCouchDocIDReader) Advance(docID index.IndexInternalID) (index.IndexInternalID, error) {
|
||||||
bir := NewBackIndexRow(docID, nil, nil)
|
|
||||||
r.iterator.Seek(bir.Key())
|
|
||||||
key, val, valid := r.iterator.Current()
|
|
||||||
r.onlyPos = sort.SearchStrings(r.only, string(docID))
|
|
||||||
|
|
||||||
if r.onlyMode {
|
if r.onlyMode {
|
||||||
|
r.onlyPos = sort.SearchStrings(r.only, string(docID))
|
||||||
|
if r.onlyPos >= len(r.only) {
|
||||||
|
// advanced to key after our last only key
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
r.iterator.Seek(NewBackIndexRow([]byte(r.only[r.onlyPos]), nil, nil).Key())
|
||||||
|
key, val, valid := r.iterator.Current()
|
||||||
|
|
||||||
var rv index.IndexInternalID
|
var rv index.IndexInternalID
|
||||||
for valid && r.onlyPos < len(r.only) {
|
for valid && r.onlyPos < len(r.only) {
|
||||||
br, err := NewBackIndexRowKV(key, val)
|
br, err := NewBackIndexRowKV(key, val)
|
||||||
@ -252,11 +256,16 @@ func (r *UpsideDownCouchDocIDReader) Advance(docID index.IndexInternalID) (index
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !bytes.Equal(br.doc, []byte(r.only[r.onlyPos])) {
|
if !bytes.Equal(br.doc, []byte(r.only[r.onlyPos])) {
|
||||||
ok := r.nextOnly()
|
// the only key we seek'd to didn't exist
|
||||||
if !ok {
|
// now look for the closest key that did exist in only
|
||||||
|
r.onlyPos = sort.SearchStrings(r.only, string(br.doc))
|
||||||
|
if r.onlyPos >= len(r.only) {
|
||||||
|
// advanced to key after our last only key
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
// now seek to this new only key
|
||||||
r.iterator.Seek(NewBackIndexRow([]byte(r.only[r.onlyPos]), nil, nil).Key())
|
r.iterator.Seek(NewBackIndexRow([]byte(r.only[r.onlyPos]), nil, nil).Key())
|
||||||
|
key, val, valid = r.iterator.Current()
|
||||||
continue
|
continue
|
||||||
} else {
|
} else {
|
||||||
rv = append([]byte(nil), br.doc...)
|
rv = append([]byte(nil), br.doc...)
|
||||||
@ -271,6 +280,9 @@ func (r *UpsideDownCouchDocIDReader) Advance(docID index.IndexInternalID) (index
|
|||||||
return rv, nil
|
return rv, nil
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
bir := NewBackIndexRow(docID, nil, nil)
|
||||||
|
r.iterator.Seek(bir.Key())
|
||||||
|
key, val, valid := r.iterator.Current()
|
||||||
if valid {
|
if valid {
|
||||||
br, err := NewBackIndexRowKV(key, val)
|
br, err := NewBackIndexRowKV(key, val)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -306,3 +306,219 @@ func TestCrashBadBackIndexRow(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIndexDocIdOnlyReader(t *testing.T) {
|
||||||
|
defer func() {
|
||||||
|
err := DestroyTest()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
analysisQueue := index.NewAnalysisQueue(1)
|
||||||
|
idx, err := NewUpsideDownCouch(boltdb.Name, boltTestConfig, analysisQueue)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
err = idx.Open()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("error opening index: %v", err)
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
err := idx.Close()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
doc := document.NewDocument("1")
|
||||||
|
err = idx.Update(doc)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Error updating index: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
doc = document.NewDocument("3")
|
||||||
|
err = idx.Update(doc)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Error updating index: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
doc = document.NewDocument("5")
|
||||||
|
err = idx.Update(doc)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Error updating index: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
doc = document.NewDocument("7")
|
||||||
|
err = idx.Update(doc)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Error updating index: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
doc = document.NewDocument("9")
|
||||||
|
err = idx.Update(doc)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Error updating index: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
indexReader, err := idx.Reader()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
err := indexReader.Close()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
onlyIds := []string{"1", "5", "9"}
|
||||||
|
reader, err := indexReader.DocIDReaderOnly(onlyIds)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Error accessing doc id reader: %v", err)
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
err := reader.Close()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
id, err := reader.Next()
|
||||||
|
count := uint64(0)
|
||||||
|
for id != nil {
|
||||||
|
count++
|
||||||
|
id, err = reader.Next()
|
||||||
|
}
|
||||||
|
if count != 3 {
|
||||||
|
t.Errorf("expected 3, got %d", count)
|
||||||
|
}
|
||||||
|
|
||||||
|
// try it again, but jump
|
||||||
|
reader2, err := indexReader.DocIDReaderOnly(onlyIds)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Error accessing doc id reader: %v", err)
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
err := reader2.Close()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
id, err = reader2.Advance(index.IndexInternalID("5"))
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if !id.Equals(index.IndexInternalID("5")) {
|
||||||
|
t.Errorf("expected to find id '5', got '%s'", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
id, err = reader2.Advance(index.IndexInternalID("a"))
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if id != nil {
|
||||||
|
t.Errorf("expected to find id '', got '%s'", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// some keys aren't actually there
|
||||||
|
onlyIds = []string{"0", "2", "4", "5", "6", "8", "a"}
|
||||||
|
reader3, err := indexReader.DocIDReaderOnly(onlyIds)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Error accessing doc id reader: %v", err)
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
err := reader3.Close()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
id, err = reader3.Next()
|
||||||
|
count = uint64(0)
|
||||||
|
for id != nil {
|
||||||
|
count++
|
||||||
|
id, err = reader3.Next()
|
||||||
|
}
|
||||||
|
if count != 1 {
|
||||||
|
t.Errorf("expected 1, got %d", count)
|
||||||
|
}
|
||||||
|
|
||||||
|
// mix advance and next
|
||||||
|
onlyIds = []string{"0", "1", "3", "5", "6", "9"}
|
||||||
|
reader4, err := indexReader.DocIDReaderOnly(onlyIds)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Error accessing doc id reader: %v", err)
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
err := reader4.Close()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// first key is "1"
|
||||||
|
id, err = reader4.Next()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if !id.Equals(index.IndexInternalID("1")) {
|
||||||
|
t.Errorf("expected to find id '1', got '%s'", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// advancing to key we dont have gives next
|
||||||
|
id, err = reader4.Advance(index.IndexInternalID("2"))
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if !id.Equals(index.IndexInternalID("3")) {
|
||||||
|
t.Errorf("expected to find id '3', got '%s'", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// next after advance works
|
||||||
|
id, err = reader4.Next()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if !id.Equals(index.IndexInternalID("5")) {
|
||||||
|
t.Errorf("expected to find id '5', got '%s'", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// advancing to key we do have works
|
||||||
|
id, err = reader4.Advance(index.IndexInternalID("9"))
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if !id.Equals(index.IndexInternalID("9")) {
|
||||||
|
t.Errorf("expected to find id '9', got '%s'", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// advance backwards at end
|
||||||
|
id, err = reader4.Advance(index.IndexInternalID("4"))
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if !id.Equals(index.IndexInternalID("5")) {
|
||||||
|
t.Errorf("expected to find id '5', got '%s'", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// next after advance works
|
||||||
|
id, err = reader4.Next()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if !id.Equals(index.IndexInternalID("9")) {
|
||||||
|
t.Errorf("expected to find id '9', got '%s'", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// advance backwards to key that exists, but not in only set
|
||||||
|
id, err = reader4.Advance(index.IndexInternalID("7"))
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if !id.Equals(index.IndexInternalID("9")) {
|
||||||
|
t.Errorf("expected to find id '9', got '%s'", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user