Tune and test Go bindings for IndexReader.
Project: http://git-wip-us.apache.org/repos/asf/lucy/repo Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/fe25122f Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/fe25122f Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/fe25122f Branch: refs/heads/master Commit: fe25122fadcb9115ddd0810e9986898048e5303e Parents: c1cdb4d Author: Marvin Humphrey <[email protected]> Authored: Tue Dec 8 20:33:58 2015 -0800 Committer: Marvin Humphrey <[email protected]> Committed: Thu Dec 10 18:22:54 2015 -0800 ---------------------------------------------------------------------- go/build.go | 5 +++ go/lucy/index.go | 47 +++++++++++++++++++++++++++ go/lucy/index_test.go | 78 +++++++++++++++++++++++++++++++++++---------- go/lucy/search_test.go | 9 +++--- 4 files changed, 118 insertions(+), 21 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucy/blob/fe25122f/go/build.go ---------------------------------------------------------------------- diff --git a/go/build.go b/go/build.go index 801654a..fc104dc 100644 --- a/go/build.go +++ b/go/build.go @@ -191,6 +191,11 @@ func specClasses(parcel *cfc.Parcel) { dataReaderBinding.SpecMethod("Close", "Close() error") dataReaderBinding.Register() + ixReaderBinding := cfc.NewGoClass(parcel, "Lucy::Index::IndexReader") + ixReaderBinding.SpecMethod("Seg_Readers", "SegReaders() []SegReader") + ixReaderBinding.SpecMethod("Offsets", "Offsets() []int32") + ixReaderBinding.SpecMethod("Obtain", "Obtain(string) (DataReader, error)") + ixReaderBinding.Register() docReaderBinding := cfc.NewGoClass(parcel, "Lucy::Index::DocReader") docReaderBinding.SpecMethod("", "ReadDoc(int32, interface{}) error") http://git-wip-us.apache.org/repos/asf/lucy/blob/fe25122f/go/lucy/index.go ---------------------------------------------------------------------- diff --git a/go/lucy/index.go b/go/lucy/index.go index 18d5ba1..67d4b47 100644 --- a/go/lucy/index.go +++ b/go/lucy/index.go @@ -18,6 +18,7 @@ package lucy /* #include "Lucy/Index/Indexer.h" +#include "Lucy/Index/IndexReader.h" #include "Lucy/Index/DataReader.h" #include "Lucy/Index/DocReader.h" #include "Lucy/Index/IndexManager.h" @@ -482,3 +483,49 @@ func (d *DocReaderIMP) FetchDoc(docID int32) (doc HitDoc, err error) { }) return doc, err } + +func OpenIndexReader(index interface{}, snapshot Snapshot, manager IndexManager) (retval IndexReader, err error) { + err = clownfish.TrapErr(func() { + indexC := (*C.cfish_Obj)(clownfish.GoToClownfish(index, unsafe.Pointer(C.CFISH_OBJ), false)) + defer C.cfish_decref(unsafe.Pointer(indexC)) + snapshotC := (*C.lucy_Snapshot)(clownfish.UnwrapNullable(snapshot)) + managerC := (*C.lucy_IndexManager)(clownfish.UnwrapNullable(manager)) + cfObj := C.lucy_IxReader_open(indexC, snapshotC, managerC) + retval = clownfish.WRAPAny(unsafe.Pointer(cfObj)).(IndexReader) + }) + return retval, err +} + +func (r *IndexReaderIMP) SegReaders() []SegReader { + self := (*C.lucy_IndexReader)(clownfish.Unwrap(r, "r")) + retvalCF := C.LUCY_IxReader_Seg_Readers(self); + defer C.cfish_decref(unsafe.Pointer(retvalCF)) + if retvalCF == nil { + return nil + } + size := C.CFISH_Vec_Get_Size(retvalCF) + retval := make([]SegReader, int(size)) + for i := 0; i < int(size); i++ { + elem := unsafe.Pointer(C.CFISH_Vec_Fetch(retvalCF, C.size_t(i))) + retval[i] = clownfish.ToGo(unsafe.Pointer(C.cfish_incref(elem))).(SegReader) + } + return retval +} + +func (r *IndexReaderIMP) Offsets() []int32 { + self := (*C.lucy_IndexReader)(clownfish.Unwrap(r, "r")) + retvalCF := C.LUCY_IxReader_Offsets(self) + defer C.cfish_decref(unsafe.Pointer(retvalCF)) + return i32ArrayToSlice(retvalCF) +} + +func (r *IndexReaderIMP) Obtain(api string) (retval DataReader, err error) { + err = clownfish.TrapErr(func() { + self := (*C.lucy_IndexReader)(clownfish.Unwrap(r, "r")) + apiC := (*C.cfish_String)(clownfish.GoToClownfish(api, unsafe.Pointer(C.CFISH_STRING), false)) + defer C.cfish_decref(unsafe.Pointer(apiC)) + retvalCF := C.LUCY_IxReader_Obtain(self, apiC) + retval = clownfish.WRAPAny(unsafe.Pointer(C.cfish_incref(unsafe.Pointer(retvalCF)))).(DataReader) + }) + return retval, err +} http://git-wip-us.apache.org/repos/asf/lucy/blob/fe25122f/go/lucy/index_test.go ---------------------------------------------------------------------- diff --git a/go/lucy/index_test.go b/go/lucy/index_test.go index 8934167..e44bb09 100644 --- a/go/lucy/index_test.go +++ b/go/lucy/index_test.go @@ -400,9 +400,9 @@ func TestSortCacheMisc(t *testing.T) { indexer.AddDoc(make(map[string]interface{})) indexer.Commit() - searcher, _ := OpenIndexSearcher(folder) - segReaders := searcher.GetReader().SegReaders() - sortReader := segReaders[0].(SegReader).Obtain("Lucy::Index::SortReader").(SortReader) + ixReader, _ := OpenIndexReader(folder, nil, nil) + segReaders := ixReader.SegReaders() + sortReader := segReaders[0].Fetch("Lucy::Index::SortReader").(SortReader) sortCache := sortReader.fetchSortCache("content") if card := sortCache.GetCardinality(); card != 4 { @@ -646,9 +646,9 @@ func TestInverterMisc(t *testing.T) { // Use SegLexicon to air out the Lexicon interface. func TestLexiconBasics(t *testing.T) { folder := createTestIndex("a", "b", "c") - searcher, _ := OpenIndexSearcher(folder) - segReaders := searcher.GetReader().SegReaders() - lexReader := segReaders[0].(SegReader).Obtain("Lucy::Index::LexiconReader").(LexiconReader) + ixReader, _ := OpenIndexReader(folder, nil, nil) + segReaders := ixReader.SegReaders() + lexReader := segReaders[0].Fetch("Lucy::Index::LexiconReader").(LexiconReader) segLex := lexReader.Lexicon("content", nil).(Lexicon) if field := segLex.getField(); field != "content" { t.Errorf("getField: %s", field) @@ -678,9 +678,9 @@ func TestLexiconBasics(t *testing.T) { func TestPostingListBasics(t *testing.T) { folder := createTestIndex("c", "b b b", "a", "b",) - searcher, _ := OpenIndexSearcher(folder) - segReaders := searcher.GetReader().SegReaders() - pListReader := segReaders[0].(SegReader).Obtain("Lucy::Index::PostingListReader").(PostingListReader) + ixReader, _ := OpenIndexReader(folder, nil, nil) + segReaders := ixReader.SegReaders() + pListReader := segReaders[0].Fetch("Lucy::Index::PostingListReader").(PostingListReader) pList := pListReader.PostingList("content", nil) pList.Seek("b") if docFreq := pList.GetDocFreq(); docFreq != 2 { @@ -746,16 +746,62 @@ func runDataReaderCommon(t *testing.T, reader DataReader, runAggregator bool) { func TestIndexReaderMisc(t *testing.T) { folder := createTestIndex("a", "b", "c") - searcher, _ := OpenIndexSearcher(folder) - reader := searcher.GetReader() + reader, _ := OpenIndexReader(folder, nil, nil) + if segReaders := reader.SegReaders(); len(segReaders) != 1 { + t.Errorf("SegReaders: %#v", segReaders) + } + if offsets := reader.Offsets(); offsets[0] != 0 { + t.Errorf("Offsets: %#v", offsets) + } + if got, err := reader.Obtain("Lucy::Index::DocReader"); got == nil || err != nil { + t.Errorf("Obtain should succeed for DocReader: %#v, %v", got, err) + } + if got, err := reader.Obtain("Nope"); got != nil || err == nil { + t.Errorf("Obtain should fail for non-existent API name: %v", err) + } + if got := reader.Fetch("Lucy::Index::DocReader"); got == nil { + t.Errorf("Fetch should succeed for DocReader") + } + if got := reader.Fetch("Nope"); got != nil { + t.Errorf("Fetch should return nil for non-existent API name: %v", got) + } + if got := reader.DocMax(); got != 3 { + t.Errorf("DocMax: %d", got); + } + if got := reader.DocCount(); got != 3 { + t.Errorf("DocCount: %d", got); + } + if got := reader.DelCount(); got != 0 { + t.Errorf("DelCount: %d", got); + } runDataReaderCommon(t, reader, false) } +func TestIndexReaderOpen(t *testing.T) { + folder := createTestIndex("a", "b", "c") + if got, err := OpenIndexReader(folder, nil, nil); got == nil || err != nil { + t.Errorf("nil Snapshot and IndexManager: %v", err) + } + snapshot := NewSnapshot() + snapshot.ReadFile(folder, "") + if got, err := OpenIndexReader(folder, snapshot, nil); got == nil || err != nil { + t.Errorf("With Snapshot: %v", err) + } + manager := NewIndexManager("", nil) + manager.SetFolder(folder) + if got, err := OpenIndexReader(folder, nil, manager); got == nil || err != nil { + t.Errorf("With IndexManager: %v", err) + } + if got, err := OpenIndexReader("no-index-here", nil, nil); got != nil || err == nil { + t.Errorf("Non-existent index path") + } +} + func TestDefaultDocReaderMisc(t *testing.T) { folder := createTestIndex("a", "b", "c") - searcher, _ := OpenIndexSearcher(folder) - segReaders := searcher.GetReader().SegReaders() - reader := segReaders[0].(SegReader).Obtain("Lucy::Index::DocReader").(DefaultDocReader) + ixReader, _ := OpenIndexReader(folder, nil, nil) + segReaders := ixReader.SegReaders() + reader := segReaders[0].Fetch("Lucy::Index::DocReader").(DefaultDocReader) doc := make(map[string]interface{}) if err := reader.ReadDoc(2, doc); err != nil { t.Errorf("ReadDoc: %v", err) @@ -765,8 +811,8 @@ func TestDefaultDocReaderMisc(t *testing.T) { func TestPolyDocReaderMisc(t *testing.T) { folder := createTestIndex("a", "b", "c") - searcher, _ := OpenIndexSearcher(folder) - reader := searcher.GetReader().Obtain("Lucy::Index::DocReader").(PolyDocReader) + ixReader, _ := OpenIndexReader(folder, nil, nil) + reader := ixReader.Fetch("Lucy::Index::DocReader").(PolyDocReader) doc := make(map[string]interface{}) if err := reader.ReadDoc(2, doc); err != nil { t.Errorf("ReadDoc: %v", err) http://git-wip-us.apache.org/repos/asf/lucy/blob/fe25122f/go/lucy/search_test.go ---------------------------------------------------------------------- diff --git a/go/lucy/search_test.go b/go/lucy/search_test.go index 3d4fc50..5061a24 100644 --- a/go/lucy/search_test.go +++ b/go/lucy/search_test.go @@ -369,12 +369,11 @@ func TestNoMatchMatcherBasics(t *testing.T) { func TestRangeMatcherBasics(t *testing.T) { index := createTestIndex("d", "c", "b", "a", "a", "a", "a") - searcher, _ := OpenIndexSearcher(index) - segReaders := searcher.GetReader().SegReaders() - segReader := segReaders[0].(SegReader) - sortReader := segReader.Obtain("Lucy::Index::SortReader").(SortReader) + ixReader, _ := OpenIndexReader(index, nil, nil) + segReaders := ixReader.SegReaders() + sortReader := segReaders[0].Fetch("Lucy::Index::SortReader").(SortReader) sortCache := sortReader.fetchSortCache("content") - matcher := NewRangeMatcher(0, 0, sortCache, segReader.DocMax()) + matcher := NewRangeMatcher(0, 0, sortCache, segReaders[0].DocMax()) if docID := matcher.Next(); docID != 4 { t.Errorf("Next: %d", docID) }
