You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by ma...@apache.org on 2015/03/19 01:22:34 UTC
[7/9] lucy git commit: Add basic Go Indexer bindings.
Add basic Go Indexer bindings.
Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/69b5681d
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/69b5681d
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/69b5681d
Branch: refs/heads/master
Commit: 69b5681d7041e4c37827f689dbdf509619e93886
Parents: 6e10881
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Sun Nov 16 22:06:58 2014 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Sun Mar 15 18:48:11 2015 -0700
----------------------------------------------------------------------
go/lucy/index.go | 166 ++++++++++++++++++++++++++++++++++++++++++++++
go/lucy/lucy_test.go | 11 ++-
2 files changed, 176 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucy/blob/69b5681d/go/lucy/index.go
----------------------------------------------------------------------
diff --git a/go/lucy/index.go b/go/lucy/index.go
new file mode 100644
index 0000000..f0e0979
--- /dev/null
+++ b/go/lucy/index.go
@@ -0,0 +1,166 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package lucy
+
+/*
+#include "Lucy/Index/Indexer.h"
+#include "Lucy/Index/IndexManager.h"
+#include "Lucy/Document/Doc.h"
+#include "Lucy/Plan/Schema.h"
+#include "Clownfish/Hash.h"
+#include "Clownfish/String.h"
+#include "Clownfish/VArray.h"
+#include "Clownfish/Err.h"
+*/
+import "C"
+import "fmt"
+import "reflect"
+import "runtime"
+import "strings"
+import "unsafe"
+import "git-wip-us.apache.org/repos/asf/lucy-clownfish.git/runtime/go/clownfish"
+
+type Indexer struct {
+ ref *C.lucy_Indexer
+ fieldNames map[string]*clownfish.String
+}
+
+type IndexManager struct {
+ ref *C.lucy_IndexManager
+}
+
+type OpenIndexerArgs struct {
+ Schema *Schema
+ Index interface{}
+ Manager *IndexManager
+ Create bool
+ Truncate bool
+}
+
+func OpenIndexer(args *OpenIndexerArgs) (obj *Indexer, err error) {
+ var schemaC *C.lucy_Schema = nil
+ if args.Schema != nil {
+ schemaC = args.Schema.ref
+ }
+ switch args.Index.(type) {
+ case string:
+ default:
+ panic("TODO: support Folder")
+ }
+ ixLoc := clownfish.NewString(args.Index.(string))
+ var managerC *C.lucy_IndexManager = nil
+ if args.Manager != nil {
+ managerC = args.Manager.ref
+ }
+ var flags int32
+ if args.Create {
+ flags = flags | int32(C.lucy_Indexer_CREATE)
+ }
+ if args.Truncate {
+ flags = flags | int32(C.lucy_Indexer_TRUNCATE)
+ }
+ err = clownfish.TrapErr(func() {
+ obj = &Indexer{
+ C.lucy_Indexer_new(schemaC, (*C.cfish_Obj)(ixLoc.ToPtr()),
+ managerC, C.int32_t(flags)),
+ nil,
+ }
+ runtime.SetFinalizer(obj, (*Indexer).finalize)
+ })
+ return obj, err
+}
+
+func (obj *Indexer) finalize() {
+ obj.Close()
+}
+
+func (obj *Indexer) Close() error {
+ // TODO: implement Close in core Lucy rather than bindings.
+ if obj.ref != nil {
+ C.cfish_dec_refcount(unsafe.Pointer(obj.ref))
+ obj.ref = nil
+ }
+ return nil // TODO catch errors
+}
+
+func (obj *Indexer) AddDoc(doc interface{}) error {
+ stockDoc := C.LUCY_Indexer_Get_Stock_Doc(obj.ref)
+ docFields := (*C.cfish_Hash)(C.LUCY_Doc_Get_Fields(stockDoc))
+ C.CFISH_Hash_Clear(docFields)
+
+ // TODO: Support map as doc in addition to struct as doc.
+
+ // Get reflection value and type for the supplied struct.
+ var docValue reflect.Value
+ if reflect.ValueOf(doc).Kind() == reflect.Ptr {
+ temp := reflect.ValueOf(doc).Elem()
+ if temp.Kind() == reflect.Struct {
+ docValue = temp
+ }
+ }
+ if docValue == (reflect.Value{}) {
+ mess := fmt.Sprintf("Doc not struct pointer: %v",
+ reflect.TypeOf(doc))
+ return clownfish.NewError(mess)
+ }
+ docType := docValue.Type()
+
+ 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_Obj)(fieldC.ToPtr()),
+ C.cfish_inc_refcount(valueC.ToPtr()))
+ }
+
+ // TODO create an additional method AddDocWithBoost which allows the
+ // client to supply `boost`.
+ boost := 1.0
+ err := clownfish.TrapErr(func() {
+ C.LUCY_Indexer_Add_Doc(obj.ref, stockDoc, C.float(boost))
+ })
+
+ return err
+}
+
+func (obj *Indexer) findFieldC(name string) *clownfish.String {
+ if obj.fieldNames == nil {
+ obj.fieldNames = make(map[string]*clownfish.String)
+ }
+ fieldC, ok := obj.fieldNames[name]
+ if !ok {
+ schema := C.LUCY_Indexer_Get_Schema(obj.ref)
+ fieldList := C.LUCY_Schema_All_Fields(schema)
+ defer C.cfish_dec_refcount(unsafe.Pointer(fieldList))
+ for i := 0; i < int(C.CFISH_VA_Get_Size(fieldList)); i++ {
+ cfString := unsafe.Pointer(C.CFISH_VA_Fetch(fieldList, C.uint32_t(i)))
+ field := clownfish.CFStringToGo(cfString)
+ if strings.EqualFold(name, field) {
+ obj.fieldNames[name] = clownfish.NewString(field)
+ fieldC = obj.fieldNames[name]
+ }
+ }
+ }
+ return fieldC
+}
+
+func (obj *Indexer) Commit() error {
+ return clownfish.TrapErr(func() {
+ C.LUCY_Indexer_Commit(obj.ref)
+ })
+}
http://git-wip-us.apache.org/repos/asf/lucy/blob/69b5681d/go/lucy/lucy_test.go
----------------------------------------------------------------------
diff --git a/go/lucy/lucy_test.go b/go/lucy/lucy_test.go
index 6a4c6d8..19b13bf 100644
--- a/go/lucy/lucy_test.go
+++ b/go/lucy/lucy_test.go
@@ -16,8 +16,17 @@
package lucy_test
-import _ "git-wip-us.apache.org/repos/asf/lucy.git/go/lucy"
+import "git-wip-us.apache.org/repos/asf/lucy.git/go/lucy"
+import "git-wip-us.apache.org/repos/asf/lucy-clownfish.git/runtime/go/clownfish"
import "testing"
func TestStuff(t *testing.T) {
+ lucy.NewSchema()
+}
+
+func TestOpenIndexer(t *testing.T) {
+ _, err := lucy.OpenIndexer(&lucy.OpenIndexerArgs{Index: "notalucyindex"})
+ if _, ok := err.(*clownfish.Err); !ok {
+ t.Error("Didn't catch exception opening indexer")
+ }
}