lucy-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mar...@apache.org
Subject [6/9] lucy git commit: Allow diff doc types in Hits.Next() Go binding.
Date Thu, 01 Oct 2015 02:13:07 GMT
Allow diff doc types in Hits.Next() Go binding.

Allow 3 different types of object to retrieve fields via Next()
*   Go struct
*   Lucy HitDoc
*   map[string]interface{}


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/1b97823d
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/1b97823d
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/1b97823d

Branch: refs/heads/master
Commit: 1b97823de7df7a09826d16070d72dd1922b73072
Parents: 853cf86
Author: Marvin Humphrey <marvin@rectangular.com>
Authored: Fri Sep 25 20:01:24 2015 -0700
Committer: Marvin Humphrey <marvin@rectangular.com>
Committed: Mon Sep 28 12:54:39 2015 -0700

----------------------------------------------------------------------
 go/lucy/search.go      | 73 ++++++++++++++++++---------------------------
 go/lucy/search_test.go | 24 +++++++++++++++
 2 files changed, 53 insertions(+), 44 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/1b97823d/go/lucy/search.go
----------------------------------------------------------------------
diff --git a/go/lucy/search.go b/go/lucy/search.go
index 514c2eb..a8bab6f 100644
--- a/go/lucy/search.go
+++ b/go/lucy/search.go
@@ -17,6 +17,9 @@
 package lucy
 
 /*
+
+#define C_LUCY_HITS
+
 #include "Lucy/Search/Collector.h"
 #include "Lucy/Search/Collector/SortCollector.h"
 #include "Lucy/Search/Hits.h"
@@ -26,6 +29,7 @@ package lucy
 #include "Lucy/Search/ANDQuery.h"
 #include "Lucy/Search/ORQuery.h"
 #include "Lucy/Search/ANDMatcher.h"
+#include "Lucy/Search/MatchDoc.h"
 #include "Lucy/Search/ORMatcher.h"
 #include "Lucy/Search/SeriesMatcher.h"
 #include "Lucy/Search/SortRule.h"
@@ -46,9 +50,6 @@ float32_set(float *floats, size_t i, float value) {
 
 */
 import "C"
-import "fmt"
-import "reflect"
-import "strings"
 import "unsafe"
 
 import "git-wip-us.apache.org/repos/asf/lucy-clownfish.git/runtime/go/clownfish"
@@ -135,52 +136,36 @@ func (obj *PolySearcherIMP) Hits(query interface{}, offset uint32, numWanted
uin
 	return doHits(obj, query, offset, numWanted, sortSpec)
 }
 
-func (obj *HitsIMP) Next(hit interface{}) bool {
-	self := ((*C.lucy_Hits)(unsafe.Pointer(obj.TOPTR())))
-	// TODO: accept a HitDoc object and populate score.
-
-	// Get reflection value and type for the supplied struct.
-	var hitValue reflect.Value
-	if reflect.ValueOf(hit).Kind() == reflect.Ptr {
-		temp := reflect.ValueOf(hit).Elem()
-		if temp.Kind() == reflect.Struct {
-			if temp.CanSet() {
-				hitValue = temp
-			}
-		}
-	}
-	if hitValue == (reflect.Value{}) {
-		mess := fmt.Sprintf("Arg not writeable struct pointer: %v",
-			reflect.TypeOf(hit))
-		obj.err = clownfish.NewErr(mess)
-		return false
-	}
+type setScorer interface {
+	SetScore(float32)
+}
 
-	var docC *C.lucy_HitDoc
-	errCallingNext := clownfish.TrapErr(func() {
-		docC = C.LUCY_Hits_Next(self)
-	})
-	if errCallingNext != nil {
-		obj.err = errCallingNext
-		return false
-	}
-	if docC == nil {
-		return false
-	}
-	defer C.cfish_dec_refcount(unsafe.Pointer(docC))
+func (h *HitsIMP) Next(hit interface{}) bool {
+	self := (*C.lucy_Hits)(clownfish.Unwrap(h, "h"))
+	ivars := C.lucy_Hits_IVARS(self)
+	matchDoc := (*C.lucy_MatchDoc)(unsafe.Pointer(
+		C.CFISH_Vec_Fetch(ivars.match_docs, C.size_t(ivars.offset))))
+	ivars.offset += 1
 
-	fields := fetchDocFields((*C.lucy_Doc)(unsafe.Pointer(docC)))
-	for key, val := range fields {
-		stringVal := val.(string) // TODO type switch
-		match := func(name string) bool {
-			return strings.EqualFold(key, name)
+	if matchDoc == nil {
+		// Bail if there aren't any more *captured* hits.  (There may be
+		// more total hits.)
+		return false
+	} else {
+		// Lazily fetch HitDoc, set score.
+		searcher := clownfish.WRAPAny(unsafe.Pointer(C.cfish_incref(
+			unsafe.Pointer(ivars.searcher)))).(Searcher)
+		docID := int32(C.LUCY_MatchDoc_Get_Doc_ID(matchDoc))
+		err := searcher.ReadDoc(docID, hit)
+		if err != nil {
+			h.err = err
+			return false
 		}
-		structField := hitValue.FieldByNameFunc(match)
-		if structField != (reflect.Value{}) {
-			structField.SetString(stringVal)
+		if ss, ok := hit.(setScorer); ok {
+			ss.SetScore(float32(C.LUCY_MatchDoc_Get_Score(matchDoc)))
 		}
+		return true
 	}
-	return true
 }
 
 func (obj *HitsIMP) Error() error {

http://git-wip-us.apache.org/repos/asf/lucy/blob/1b97823d/go/lucy/search_test.go
----------------------------------------------------------------------
diff --git a/go/lucy/search_test.go b/go/lucy/search_test.go
index d0668ae..ae4c352 100644
--- a/go/lucy/search_test.go
+++ b/go/lucy/search_test.go
@@ -438,6 +438,30 @@ func TestHitsBasics(t *testing.T) {
 	}
 }
 
+func TestHitsNext(t *testing.T) {
+	index := createTestIndex("a x", "a y", "a z", "b")
+	searcher, _ := OpenIndexSearcher(index)
+	hits, _ := searcher.Hits("a", 0, 10, nil)
+	docDoc := NewHitDoc(0, -1.0)
+	docStruct := &simpleTestDoc{}
+	docMap := make(map[string]interface{})
+	if !hits.Next(docDoc) || !hits.Next(docStruct) || !hits.Next(docMap) {
+		t.Errorf("Hits.Next returned false: %v", hits.Error())
+	}
+	if hits.Next(&simpleTestDoc{}) {
+		t.Error("Hits iterator should be exhausted");
+	}
+	if docDoc.Extract("content").(string) != "a x" {
+		t.Error("Next with Doc object yielded bad data")
+	}
+	if docStruct.Content != "a y" {
+		t.Error("Next with struct yielded bad data")
+	}
+	if docMap["content"].(string) != "a z" {
+		t.Error("Next with map yielded bad data")
+	}
+}
+
 func TestSortSpecBasics(t *testing.T) {
 	folder := NewRAMFolder("")
 	schema := NewSchema()


Mime
View raw message