Port Inverter and InverterEntry to CGO.
Project: http://git-wip-us.apache.org/repos/asf/lucy/repo Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/acd74d27 Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/acd74d27 Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/acd74d27 Branch: refs/heads/master Commit: acd74d27985e635606c775a44d7c5c718583d76f Parents: 8f63442 Author: Marvin Humphrey <[email protected]> Authored: Sat Jul 18 14:49:30 2015 -0700 Committer: Marvin Humphrey <[email protected]> Committed: Fri Jul 31 17:59:21 2015 -0700 ---------------------------------------------------------------------- go/cfext/lucy.c | 76 +------------------------------------- go/lucy/lucy.go | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 102 insertions(+), 75 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucy/blob/acd74d27/go/cfext/lucy.c ---------------------------------------------------------------------- diff --git a/go/cfext/lucy.c b/go/cfext/lucy.c index e2719bc..f10a23f 100644 --- a/go/cfext/lucy.c +++ b/go/cfext/lucy.c @@ -249,83 +249,11 @@ DefDocReader_Fetch_Doc_IMP(DefaultDocReader *self, int32_t doc_id) { /**************************** Inverter *****************************/ -static InverterEntry* -S_fetch_entry(InverterIVARS *ivars, String *field) { - Schema *const schema = ivars->schema; - int32_t field_num = Seg_Field_Num(ivars->segment, field); - if (!field_num) { - // This field seems not to be in the segment yet. Try to find it in - // the Schema. - if (Schema_Fetch_Type(schema, field)) { - // The field is in the Schema. Get a field num from the Segment. - field_num = Seg_Add_Field(ivars->segment, field); - } - else { - // We've truly failed to find the field. The user must - // not have spec'd it. - THROW(ERR, "Unknown field name: '%o'", field); - } - } - - InverterEntry *entry - = (InverterEntry*)Vec_Fetch(ivars->entry_pool, field_num); - if (!entry) { - entry = InvEntry_new(schema, (String*)field, field_num); - Vec_Store(ivars->entry_pool, field_num, (Obj*)entry); - } - return entry; -} +Inverter_Invert_Doc_t GOLUCY_Inverter_Invert_Doc_BRIDGE; void Inverter_Invert_Doc_IMP(Inverter *self, Doc *doc) { - InverterIVARS *const ivars = Inverter_IVARS(self); - Hash *const fields = (Hash*)Doc_Get_Fields(doc); - - // Prepare for the new doc. - Inverter_Set_Doc(self, doc); - - // Extract and invert the doc's fields. - HashIterator *iter = HashIter_new(fields); - while (HashIter_Next(iter)) { - String *field = HashIter_Get_Key(iter); - Obj *obj = HashIter_Get_Value(iter); - - InverterEntry *inventry = S_fetch_entry(ivars, field); - InverterEntryIVARS *inventry_ivars = InvEntry_IVARS(inventry); - FieldType *type = inventry_ivars->type; - - // Get the field value. - switch (FType_Primitive_ID(type) & FType_PRIMITIVE_ID_MASK) { - case FType_TEXT: { - CERTIFY(obj, STRING); - break; - } - case FType_BLOB: { - CERTIFY(obj, BLOB); - break; - } - case FType_INT32: - case FType_INT64: { - CERTIFY(obj, INTEGER); - break; - } - case FType_FLOAT32: - case FType_FLOAT64: { - CERTIFY(obj, FLOAT); - break; - } - default: - THROW(ERR, "Unrecognized type: %o", type); - } - - if (inventry_ivars->value != obj) { - DECREF(inventry_ivars->value); - inventry_ivars->value = INCREF(obj); - } - - Inverter_Add_Field(self, inventry); - } - DECREF(iter); + GOLUCY_Inverter_Invert_Doc_BRIDGE(self, doc); } http://git-wip-us.apache.org/repos/asf/lucy/blob/acd74d27/go/lucy/lucy.go ---------------------------------------------------------------------- diff --git a/go/lucy/lucy.go b/go/lucy/lucy.go index 7d55798..664a200 100644 --- a/go/lucy/lucy.go +++ b/go/lucy/lucy.go @@ -19,12 +19,20 @@ package lucy /* #define C_LUCY_DOC #define C_LUCY_REGEXTOKENIZER +#define C_LUCY_INVERTER +#define C_LUCY_INVERTERENTRY #include "lucy_parcel.h" #include "Lucy/Analysis/RegexTokenizer.h" #include "Lucy/Document/Doc.h" +#include "Lucy/Index/Inverter.h" #include "Clownfish/Hash.h" +#include "Clownfish/HashIterator.h" +#include "Clownfish/Vector.h" +#include "Lucy/Plan/FieldType.h" +#include "Lucy/Plan/Schema.h" +#include "Lucy/Index/Segment.h" #include "Lucy/Store/InStream.h" #include "Lucy/Store/OutStream.h" #include "Lucy/Util/Freezer.h" @@ -82,6 +90,10 @@ GOLUCY_Doc_Destroy(lucy_Doc *self); extern void (*GOLUCY_Doc_Destroy_BRIDGE)(lucy_Doc *self); +extern void +GOLUCY_Inverter_Invert_Doc(lucy_Inverter *self, lucy_Doc *doc); +extern void +(*GOLUCY_Inverter_Invert_Doc_BRIDGE)(lucy_Inverter *self, lucy_Doc *doc); // C symbols linked into a Go-built package archive are not visible to @@ -103,12 +115,14 @@ GOLUCY_glue_exported_symbols() { GOLUCY_Doc_Extract_BRIDGE = GOLUCY_Doc_Extract; GOLUCY_Doc_Equals_BRIDGE = GOLUCY_Doc_Equals; GOLUCY_Doc_Destroy_BRIDGE = GOLUCY_Doc_Destroy; + GOLUCY_Inverter_Invert_Doc_BRIDGE = GOLUCY_Inverter_Invert_Doc; } */ import "C" import "unsafe" -import _ "git-wip-us.apache.org/repos/asf/lucy-clownfish.git/runtime/go/clownfish" +import "fmt" +import "git-wip-us.apache.org/repos/asf/lucy-clownfish.git/runtime/go/clownfish" func init() { C.GOLUCY_glue_exported_symbols() @@ -214,3 +228,88 @@ func GOLUCY_Doc_Destroy(d *C.lucy_Doc) { C.cfish_decref(unsafe.Pointer(ivars.fields)) C.cfish_super_destroy(unsafe.Pointer(d), C.LUCY_DOC) } + +func fetchEntry(ivars *C.lucy_InverterIVARS, field *C.cfish_String) *C.lucy_InverterEntry { + schema := ivars.schema + fieldNum := C.LUCY_Seg_Field_Num(ivars.segment, field) + if fieldNum == 0 { + // This field seems not to be in the segment yet. Try to find it in + // the Schema. + if C.LUCY_Schema_Fetch_Type(schema, field) != nil { + // The field is in the Schema. Get a field num from the Segment. + fieldNum = C.LUCY_Seg_Add_Field(ivars.segment, field) + } else { + // We've truly failed to find the field. The user must + // not have spec'd it. + fieldGo := clownfish.CFStringToGo(unsafe.Pointer(field)) + err := clownfish.NewErr("Unknown field name: '" + fieldGo + "'") + panic(err) + } + } + entry := C.CFISH_Vec_Fetch(ivars.entry_pool, C.size_t(fieldNum)) + if entry == nil { + newEntry := C.lucy_InvEntry_new(schema, field, fieldNum) + C.CFISH_Vec_Store(ivars.entry_pool, C.size_t(fieldNum), + (*C.cfish_Obj)(unsafe.Pointer(entry))) + return newEntry + } + return (*C.lucy_InverterEntry)(unsafe.Pointer(entry)) +} + +//export GOLUCY_Inverter_Invert_Doc +func GOLUCY_Inverter_Invert_Doc(inverter *C.lucy_Inverter, doc *C.lucy_Doc) { + ivars := C.lucy_Inverter_IVARS(inverter) + fields := (*C.cfish_Hash)(C.LUCY_Doc_Get_Fields(doc)) + + // Prepare for the new 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)) + } + + inventry := fetchEntry(ivars, field) + inventryIvars := C.lucy_InvEntry_IVARS(inventry) + fieldType := inventryIvars._type + + // Get the field value. + var expectedType *C.cfish_Class + switch C.LUCY_FType_Primitive_ID(fieldType) & C.lucy_FType_PRIMITIVE_ID_MASK { + case C.lucy_FType_TEXT: + expectedType = C.CFISH_STRING + case C.lucy_FType_BLOB: + expectedType = C.CFISH_BLOB + case C.lucy_FType_INT32: + expectedType = C.CFISH_INTEGER + case C.lucy_FType_INT64: + expectedType = C.CFISH_INTEGER + case C.lucy_FType_FLOAT32: + expectedType = C.CFISH_FLOAT + 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)) + } + + C.LUCY_Inverter_Add_Field(inverter, inventry) + } + C.cfish_dec_refcount(unsafe.Pointer(iter)) +}
