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 <[email protected]>
Authored: Tue Sep 15 20:25:31 2015 -0700
Committer: Marvin Humphrey <[email protected]>
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