[Groonga-commit] groonga/grngo at 4a5241f [master] Update GetValue() to support deep vectors.

Back to archive index

susumu.yata null+****@clear*****
Wed Jul 29 07:54:01 JST 2015


susumu.yata	2015-07-29 07:54:01 +0900 (Wed, 29 Jul 2015)

  New Revision: 4a5241f8fb3ab41f520749917df2ea59310fd106
  https://github.com/groonga/grngo/commit/4a5241f8fb3ab41f520749917df2ea59310fd106

  Message:
    Update GetValue() to support deep vectors.
    
    GitHub: #18

  Modified files:
    grngo.go

  Modified: grngo.go (+75 -5)
===================================================================
--- grngo.go    2015-07-28 12:27:16 +0900 (0a31962)
+++ grngo.go    2015-07-29 07:54:01 +0900 (a21878b)
@@ -1183,19 +1183,89 @@ func (column *Column) parseVector(ptr unsafe.Pointer) (interface{}, error) {
 	}
 }
 
+func (column *Column) getType() (reflect.Type, error) {
+	switch column.c.value_type {
+	case C.GRN_DB_BOOL:
+		var dummy bool
+		return reflect.TypeOf(dummy), nil
+	case C.GRN_DB_INT8, C.GRN_DB_INT16, C.GRN_DB_INT32, C.GRN_DB_INT64,
+		C.GRN_DB_UINT8, C.GRN_DB_UINT16, C.GRN_DB_UINT32, C.GRN_DB_UINT64:
+		var dummy int64
+		return reflect.TypeOf(dummy), nil
+	case C.GRN_DB_FLOAT:
+		var dummy float64
+		return reflect.TypeOf(dummy), nil
+	case C.GRN_DB_TIME:
+		var dummy int64
+		return reflect.TypeOf(dummy), nil
+	case C.GRN_DB_SHORT_TEXT, C.GRN_DB_TEXT, C.GRN_DB_LONG_TEXT:
+		var dummy []byte
+		return reflect.TypeOf(dummy), nil
+	case C.GRN_DB_TOKYO_GEO_POINT, C.GRN_DB_WGS84_GEO_POINT:
+		var dummy GeoPoint
+		return reflect.TypeOf(dummy), nil
+	default:
+		return nil, fmt.Errorf("unknown data type")
+	}
+}
+
+func (column *Column) parse(typ reflect.Type, depth int, ptr unsafe.Pointer) (reflect.Value, error) {
+	dimension := int(column.c.dimension)
+	if (depth == (dimension - 1)) {
+		value, err := column.parseVector(ptr)
+		if err != nil {
+			return reflect.Zero(reflect.SliceOf(typ)), err
+		}
+		return reflect.ValueOf(value), nil
+	}
+	sType := typ
+	for i := depth; i < int(column.c.dimension); i++ {
+		sType = reflect.SliceOf(sType)
+	}
+	vector := *(*C.grngo_vector)(ptr)
+	header := reflect.SliceHeader{
+		Data: uintptr(vector.ptr),
+		Len:  int(vector.size),
+		Cap:  int(vector.size),
+	}
+	cValue := *(*[]C.grngo_vector)(unsafe.Pointer(&header))
+	value := reflect.MakeSlice(sType, 0, len(cValue))
+	for i := 0; i < len(cValue); i++ {
+		newValue, err := column.parse(typ, depth + 1, unsafe.Pointer(&cValue[i]))
+		if err != nil {
+			return reflect.Zero(sType), err
+		}
+		value = reflect.Append(value, newValue)
+	}
+	return value, nil
+}
+
+// parseDeepVector parses a deep vector.
+func (column *Column) parseDeepVector(ptr unsafe.Pointer) (interface{}, error) {
+	typ, err := column.getType()
+	if err != nil {
+		return nil, err
+	}
+	value, err := column.parse(typ, 0, ptr)
+	if err != nil {
+		return nil, err
+	}
+	return value.Interface(), nil
+}
+
 // GetValue gets a value.
 func (column *Column) GetValue(id uint32) (interface{}, error) {
-	if column.c.dimension > 1 {
-		return nil, fmt.Errorf("Deep vectors are not supported yet")
-	}
 	var ptr unsafe.Pointer
 	rc := C.grngo_get(column.c, C.grn_id(id), &ptr)
 	if rc != C.GRN_SUCCESS {
 		return nil, newGrnError("grngo_get()", rc, column.table.db)
 	}
-	if column.c.dimension == 0 {
+	switch column.c.dimension {
+	case 0:
 		return column.parseScalar(ptr)
-	} else {
+	case 1:
 		return column.parseVector(ptr)
+	default:
+		return column.parseDeepVector(ptr)
 	}
 }
-------------- next part --------------
HTML����������������������������...
Download 



More information about the Groonga-commit mailing list
Back to archive index