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")
+	}
 }