lucy-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mar...@apache.org
Subject [3/9] lucy git commit: Switch Doc to `map[string]interface{}`.
Date Thu, 01 Oct 2015 02:13:04 GMT
Switch Doc to `map[string]interface{}`.

Change from Clownfish Hash to Go map.


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

Branch: refs/heads/master
Commit: 8223307d126898cee43286e1e7bafb6f6d149c25
Parents: a41f86c
Author: Marvin Humphrey <marvin@rectangular.com>
Authored: Tue Sep 15 20:25:31 2015 -0700
Committer: Marvin Humphrey <marvin@rectangular.com>
Committed: Mon Sep 28 12:54:38 2015 -0700

----------------------------------------------------------------------
 go/lucy/document.go |   6 +--
 go/lucy/index.go    |  24 +++++------
 go/lucy/lucy.go     | 107 +++++++++++++++++++++++------------------------
 go/lucy/search.go   |  11 ++---
 4 files changed, 69 insertions(+), 79 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/8223307d/go/lucy/document.go
----------------------------------------------------------------------
diff --git a/go/lucy/document.go b/go/lucy/document.go
index 3196986..1221810 100644
--- a/go/lucy/document.go
+++ b/go/lucy/document.go
@@ -39,12 +39,12 @@ func NewHitDoc(docID int32, score float32) HitDoc {
 	return WRAPHitDoc(unsafe.Pointer(retvalCF))
 }
 
-func fetchDocFields(d *C.lucy_Doc) *C.cfish_Hash {
+func fetchDocFields(d *C.lucy_Doc) map[string]interface{} {
 	ivars := C.lucy_Doc_IVARS(d)
 	fieldsID := uintptr(ivars.fields)
-	fieldsGo, ok := registry.fetch(fieldsID).(clownfish.Hash)
+	fieldsGo, ok := registry.fetch(fieldsID).(map[string]interface{})
 	if !ok {
 		panic(clownfish.NewErr(fmt.Sprintf("Failed to fetch doc %d from registry ", fieldsID)))
 	}
-	return (*C.cfish_Hash)(clownfish.Unwrap(fieldsGo, "fieldsGo"))
+	return fieldsGo
 }

http://git-wip-us.apache.org/repos/asf/lucy/blob/8223307d/go/lucy/index.go
----------------------------------------------------------------------
diff --git a/go/lucy/index.go b/go/lucy/index.go
index 6543c99..1662d3e 100644
--- a/go/lucy/index.go
+++ b/go/lucy/index.go
@@ -35,7 +35,7 @@ import "git-wip-us.apache.org/repos/asf/lucy-clownfish.git/runtime/go/clownfish"
 
 type IndexerIMP struct {
 	clownfish.ObjIMP
-	fieldNames map[string]clownfish.String
+	fieldNames map[string]string
 }
 
 type OpenIndexerArgs struct {
@@ -74,7 +74,9 @@ func (obj *IndexerIMP) AddDoc(doc interface{}) error {
 	self := ((*C.lucy_Indexer)(unsafe.Pointer(obj.TOPTR())))
 	stockDoc := C.LUCY_Indexer_Get_Stock_Doc(self)
 	docFields := fetchDocFields(stockDoc)
-	C.CFISH_Hash_Clear(docFields)
+	for field := range docFields {
+		delete(docFields, field)
+	}
 
 	// TODO: Support map as doc in addition to struct as doc.
 
@@ -96,11 +98,8 @@ func (obj *IndexerIMP) AddDoc(doc interface{}) error {
 	for i := 0; i < docValue.NumField(); i++ {
 		field := docType.Field(i).Name
 		value := docValue.Field(i).String()
-		fieldC := obj.findFieldC(field)
-		valueC := clownfish.NewString(value)
-		C.CFISH_Hash_Store(docFields,
-			(*C.cfish_String)(unsafe.Pointer(fieldC)),
-			C.cfish_inc_refcount(unsafe.Pointer(valueC.TOPTR())))
+		realField := obj.findRealField(field)
+		docFields[realField] = value
 	}
 
 	// TODO create an additional method AddDocWithBoost which allows the
@@ -113,10 +112,10 @@ func (obj *IndexerIMP) AddDoc(doc interface{}) error {
 	return err
 }
 
-func (obj *IndexerIMP) findFieldC(name string) *C.cfish_String {
+func (obj *IndexerIMP) findRealField(name string) string {
 	self := ((*C.lucy_Indexer)(unsafe.Pointer(obj.TOPTR())))
 	if obj.fieldNames == nil {
-		obj.fieldNames = make(map[string]clownfish.String)
+		obj.fieldNames = make(map[string]string)
 	}
 	f, ok := obj.fieldNames[name]
 	if !ok {
@@ -127,13 +126,12 @@ func (obj *IndexerIMP) findFieldC(name string) *C.cfish_String {
 			cfString := unsafe.Pointer(C.CFISH_Vec_Fetch(fieldList, C.size_t(i)))
 			field := clownfish.CFStringToGo(cfString)
 			if strings.EqualFold(name, field) {
-				C.cfish_inc_refcount(cfString)
-				f = clownfish.WRAPString(cfString)
-				obj.fieldNames[name] = f
+				f = field
+				obj.fieldNames[name] = field
 			}
 		}
 	}
-	return (*C.cfish_String)(unsafe.Pointer(f.TOPTR()))
+	return f
 }
 
 func (obj *IndexerIMP) Commit() error {

http://git-wip-us.apache.org/repos/asf/lucy/blob/8223307d/go/lucy/lucy.go
----------------------------------------------------------------------
diff --git a/go/lucy/lucy.go b/go/lucy/lucy.go
index 50ac2c9..36868bd 100644
--- a/go/lucy/lucy.go
+++ b/go/lucy/lucy.go
@@ -183,6 +183,7 @@ import "C"
 import "unsafe"
 import "fmt"
 import "regexp"
+import "reflect"
 import "git-wip-us.apache.org/repos/asf/lucy-clownfish.git/runtime/go/clownfish"
 
 var registry *objRegistry
@@ -253,7 +254,8 @@ func GOLUCY_RegexTokenizer_Tokenize_Utf8(rt *C.lucy_RegexTokenizer, str
*C.char,
 func GOLUCY_Doc_init(d *C.lucy_Doc, fields unsafe.Pointer, docID C.int32_t) *C.lucy_Doc {
 	ivars := C.lucy_Doc_IVARS(d)
 	if fields == nil {
-		fieldsID := registry.store(clownfish.NewHash(0))
+		fieldsGo := make(map[string]interface{})
+		fieldsID := registry.store(fieldsGo)
 		ivars.fields = unsafe.Pointer(fieldsID)
 	} else {
 		ivars.fields = fields
@@ -269,21 +271,25 @@ func GOLUCY_Doc_Set_Fields(d *C.lucy_Doc, fields unsafe.Pointer) {
 
 //export GOLUCY_Doc_Get_Size
 func GOLUCY_Doc_Get_Size(d *C.lucy_Doc) C.uint32_t {
-	hash := fetchDocFields(d)
-	return C.uint32_t(C.CFISH_Hash_Get_Size(hash))
+	fields := fetchDocFields(d)
+	return C.uint32_t(len(fields))
 }
 
 //export GOLUCY_Doc_Store
 func GOLUCY_Doc_Store(d *C.lucy_Doc, field *C.cfish_String, value *C.cfish_Obj) {
-	hash := fetchDocFields(d)
-	C.CFISH_Hash_Store(hash, field, C.cfish_inc_refcount(unsafe.Pointer(value)))
+	fields := fetchDocFields(d)
+	fieldGo := clownfish.CFStringToGo(unsafe.Pointer(field))
+	valGo := clownfish.ToGo(unsafe.Pointer(value))
+	fields[fieldGo] = valGo
 }
 
 //export GOLUCY_Doc_Serialize
 func GOLUCY_Doc_Serialize(d *C.lucy_Doc, outstream *C.lucy_OutStream) {
 	ivars := C.lucy_Doc_IVARS(d)
-	hash := fetchDocFields(d)
-	C.lucy_Freezer_serialize_hash(hash, outstream)
+	fields := fetchDocFields(d)
+	hash := clownfish.GoToClownfish(fields, unsafe.Pointer(C.CFISH_HASH), false)
+	defer C.cfish_decref(hash)
+	C.lucy_Freezer_serialize_hash((*C.cfish_Hash)(hash), outstream)
 	C.LUCY_OutStream_Write_C32(outstream, C.uint32_t(ivars.doc_id))
 }
 
@@ -291,7 +297,9 @@ func GOLUCY_Doc_Serialize(d *C.lucy_Doc, outstream *C.lucy_OutStream)
{
 func GOLUCY_Doc_Deserialize(d *C.lucy_Doc, instream *C.lucy_InStream) *C.lucy_Doc {
 	ivars := C.lucy_Doc_IVARS(d)
 	hash := unsafe.Pointer(C.lucy_Freezer_read_hash(instream))
-	fieldsID := registry.store(clownfish.WRAPAny(hash))
+	defer C.cfish_decref(hash)
+	fields := clownfish.ToGo(hash)
+	fieldsID := registry.store(fields)
 	ivars.fields = unsafe.Pointer(fieldsID)
 	ivars.doc_id = C.int32_t(C.LUCY_InStream_Read_C32(instream))
 	return d
@@ -299,15 +307,20 @@ func GOLUCY_Doc_Deserialize(d *C.lucy_Doc, instream *C.lucy_InStream)
*C.lucy_Do
 
 //export GOLUCY_Doc_Extract
 func GOLUCY_Doc_Extract(d *C.lucy_Doc, field *C.cfish_String) *C.cfish_Obj {
-	hash := fetchDocFields(d)
-	val := C.CFISH_Hash_Fetch(hash, field)
-	return C.cfish_inc_refcount(unsafe.Pointer(val))
+	fields := fetchDocFields(d)
+	fieldGo := clownfish.CFStringToGo(unsafe.Pointer(field))
+	return (*C.cfish_Obj)(clownfish.GoToClownfish(fields[fieldGo],
+		unsafe.Pointer(C.CFISH_OBJ), true))
 }
 
 //export GOLUCY_Doc_Field_Names
 func GOLUCY_Doc_Field_Names(d *C.lucy_Doc) *C.cfish_Vector {
-	hash := fetchDocFields(d)
-	return C.CFISH_Hash_Keys(hash)
+	fields := fetchDocFields(d)
+	vec := clownfish.NewVector(len(fields))
+	for key, _ := range fields {
+		vec.Push(key)
+	}
+	return (*C.cfish_Vector)(C.cfish_incref(clownfish.Unwrap(vec, "vec")))
 }
 
 //export GOLUCY_Doc_Equals
@@ -319,9 +332,10 @@ func GOLUCY_Doc_Equals(d *C.lucy_Doc, other *C.cfish_Obj) C.bool {
 	if !C.cfish_Obj_is_a(other, C.LUCY_DOC) {
 		return false
 	}
-	hash := fetchDocFields(d)
-	otherHash := (*C.cfish_Obj)(unsafe.Pointer(fetchDocFields(twin)))
-	return C.CFISH_Hash_Equals(hash, otherHash)
+	fields := fetchDocFields(d)
+	otherFields := fetchDocFields(twin)
+	result := reflect.DeepEqual(fields, otherFields)
+	return C.bool(result)
 }
 
 //export GOLUCY_Doc_Destroy
@@ -332,7 +346,10 @@ func GOLUCY_Doc_Destroy(d *C.lucy_Doc) {
 	C.cfish_super_destroy(unsafe.Pointer(d), C.LUCY_DOC)
 }
 
-func fetchEntry(ivars *C.lucy_InverterIVARS, field *C.cfish_String) *C.lucy_InverterEntry
{
+func fetchEntry(ivars *C.lucy_InverterIVARS, fieldGo string) *C.lucy_InverterEntry {
+	field := (*C.cfish_String)(clownfish.GoToClownfish(fieldGo,
+		unsafe.Pointer(C.CFISH_STRING), false))
+	defer C.cfish_decref(unsafe.Pointer(field))
 	schema := ivars.schema
 	fieldNum := C.LUCY_Seg_Field_Num(ivars.segment, field)
 	if fieldNum == 0 {
@@ -366,7 +383,7 @@ func GOLUCY_DefDocReader_Fetch_Doc(ddr *C.lucy_DefaultDocReader,
 	schema := ivars.schema
 	datInstream := ivars.dat_in
 	ixInstream := ivars.ix_in
-	fields := C.cfish_Hash_new(1)
+	fields := make(map[string]interface{})
 	fieldNameCap := C.size_t(31)
 	var fieldName *C.char = ((*C.char)(C.malloc(fieldNameCap + 1)))
 
@@ -391,43 +408,40 @@ func GOLUCY_DefDocReader_Fetch_Doc(ddr *C.lucy_DefaultDocReader,
 		// inefficient.  The solution should be to add a privte
 		// Schema_Fetch_Type_Utf8 method which takes char* and size_t.
 		fieldNameStr := C.cfish_Str_new_from_utf8(fieldName, fieldNameLen)
+		fieldNameGo := C.GoStringN(fieldName, C.int(fieldNameLen))
 		fieldType := C.LUCY_Schema_Fetch_Type(schema, fieldNameStr)
 		C.cfish_dec_refcount(unsafe.Pointer(fieldNameStr))
 
 		// Read the field value.
-		var value *C.cfish_Obj
 		switch C.LUCY_FType_Primitive_ID(fieldType) & C.lucy_FType_PRIMITIVE_ID_MASK {
 		case C.lucy_FType_TEXT:
 			valueLen := C.size_t(C.LUCY_InStream_Read_C32(datInstream))
 			buf := ((*C.char)(C.malloc(valueLen + 1)))
 			C.LUCY_InStream_Read_Bytes(datInstream, buf, valueLen)
-			C.null_terminate_string(buf, valueLen)
-			value = ((*C.cfish_Obj)(C.cfish_Str_new_steal_utf8(buf, valueLen)))
+			val := C.GoStringN(buf, C.int(valueLen))
+			fields[fieldNameGo] = val
 		case C.lucy_FType_BLOB:
 			valueLen := C.size_t(C.LUCY_InStream_Read_C32(datInstream))
 			buf := ((*C.char)(C.malloc(valueLen)))
 			C.LUCY_InStream_Read_Bytes(datInstream, buf, valueLen)
-			value = ((*C.cfish_Obj)(C.cfish_Blob_new_steal(buf, valueLen)))
+			val := C.GoBytes(unsafe.Pointer(buf), C.int(valueLen))
+			fields[fieldNameGo] = val
 		case C.lucy_FType_FLOAT32:
-			value = ((*C.cfish_Obj)(C.cfish_Float_new(C.double(C.LUCY_InStream_Read_F32(datInstream)))))
+			fields[fieldNameGo] = float32(C.LUCY_InStream_Read_F32(datInstream))
 		case C.lucy_FType_FLOAT64:
-			value = ((*C.cfish_Obj)(C.cfish_Float_new(C.LUCY_InStream_Read_F64(datInstream))))
+			fields[fieldNameGo] = float64(C.LUCY_InStream_Read_F64(datInstream))
 		case C.lucy_FType_INT32:
-			value = ((*C.cfish_Obj)(C.cfish_Int_new(C.int64_t(C.LUCY_InStream_Read_C32(datInstream)))))
+			fields[fieldNameGo] = int32(C.LUCY_InStream_Read_C32(datInstream))
 		case C.lucy_FType_INT64:
-			value = ((*C.cfish_Obj)(C.cfish_Int_new(C.int64_t(C.LUCY_InStream_Read_C64(datInstream)))))
+			fields[fieldNameGo] = int32(C.LUCY_InStream_Read_C64(datInstream))
 		default:
-			value = nil
 			panic(clownfish.NewErr("Internal Lucy error: bad type id for field " +
-				C.GoStringN(fieldName, C.int(fieldNameLen))))
+				fieldNameGo))
 		}
-
-		// Store the value.
-		C.CFISH_Hash_Store_Utf8(fields, fieldName, fieldNameLen, value)
 	}
 	C.free(unsafe.Pointer(fieldName))
 
-	fieldsID := registry.store(clownfish.WRAPAny(unsafe.Pointer(fields)))
+	fieldsID := registry.store(fields)
 	retval := C.lucy_HitDoc_new(unsafe.Pointer(fieldsID), docID, 0.0)
 	return retval
 }
@@ -441,15 +455,7 @@ func GOLUCY_Inverter_Invert_Doc(inverter *C.lucy_Inverter, doc *C.lucy_Doc)
{
 	C.LUCY_Inverter_Set_Doc(inverter, doc)
 
 	// Extract and invert the doc's fields.
-	iter := C.cfish_HashIter_new(fields)
-	for C.CFISH_HashIter_Next(iter) {
-		field := C.CFISH_HashIter_Get_Key(iter)
-		obj := C.CFISH_HashIter_Get_Value(iter)
-		if obj == nil {
-			mess := "Invalid nil value for field" + clownfish.CFStringToGo(unsafe.Pointer(field))
-			panic(clownfish.NewErr(mess))
-		}
-
+	for field, val := range(fields) {
 		inventry := fetchEntry(ivars, field)
 		inventryIvars := C.lucy_InvEntry_IVARS(inventry)
 		fieldType := inventryIvars._type
@@ -470,22 +476,13 @@ func GOLUCY_Inverter_Invert_Doc(inverter *C.lucy_Inverter, doc *C.lucy_Doc)
{
 		case C.lucy_FType_FLOAT64:
 			expectedType = C.CFISH_FLOAT
 		default:
-			panic(clownfish.NewErr("Internal Lucy error: bad type id for field " +
-				clownfish.CFStringToGo(unsafe.Pointer(field))))
-		}
-		if !C.cfish_Obj_is_a(obj, expectedType) {
-			className := C.cfish_Obj_get_class_name((*C.cfish_Obj)(unsafe.Pointer(fieldType)))
-			mess := fmt.Sprintf("Invalid type for field '%s': '%s'",
-				clownfish.CFStringToGo(unsafe.Pointer(field)),
-				clownfish.CFStringToGo(unsafe.Pointer(className)))
-			panic(clownfish.NewErr(mess))
-		}
-		if inventryIvars.value != obj {
-			C.cfish_decref(unsafe.Pointer(inventryIvars.value))
-			inventryIvars.value = C.cfish_inc_refcount(unsafe.Pointer(obj))
+			panic(clownfish.NewErr("Internal Lucy error: bad type id for field " + field))
 		}
+		temp := inventryIvars.value
+		valCF := clownfish.GoToClownfish(val, unsafe.Pointer(expectedType), false)
+		inventryIvars.value = C.cfish_inc_refcount(valCF)
+		C.cfish_decref(unsafe.Pointer(temp))
 
 		C.LUCY_Inverter_Add_Field(inverter, inventry)
 	}
-	C.cfish_dec_refcount(unsafe.Pointer(iter))
 }

http://git-wip-us.apache.org/repos/asf/lucy/blob/8223307d/go/lucy/search.go
----------------------------------------------------------------------
diff --git a/go/lucy/search.go b/go/lucy/search.go
index 7f6ce76..ed1b5e4 100644
--- a/go/lucy/search.go
+++ b/go/lucy/search.go
@@ -150,19 +150,14 @@ func (obj *HitsIMP) Next(hit interface{}) bool {
 	defer C.cfish_dec_refcount(unsafe.Pointer(docC))
 
 	fields := fetchDocFields((*C.lucy_Doc)(unsafe.Pointer(docC)))
-	iterator := C.cfish_HashIter_new(fields)
-	defer C.cfish_dec_refcount(unsafe.Pointer(iterator))
-	for C.CFISH_HashIter_Next(iterator) {
-		keyC := C.CFISH_HashIter_Get_Key(iterator)
-		valC := C.CFISH_HashIter_Get_Value(iterator)
-		key := clownfish.CFStringToGo(unsafe.Pointer(keyC))
-		val := clownfish.CFStringToGo(unsafe.Pointer(valC))
+	for key, val := range fields {
+		stringVal := val.(string) // TODO type switch
 		match := func(name string) bool {
 			return strings.EqualFold(key, name)
 		}
 		structField := hitValue.FieldByNameFunc(match)
 		if structField != (reflect.Value{}) {
-			structField.SetString(val)
+			structField.SetString(stringVal)
 		}
 	}
 	return true


Mime
View raw message