[Groonga-commit] groonga/grnxx at 57faf5c [master] Gnx: support GeoPoint.

Back to archive index

susumu.yata null+****@clear*****
Thu Apr 9 19:02:26 JST 2015


susumu.yata	2015-04-09 19:02:26 +0900 (Thu, 09 Apr 2015)

  New Revision: 57faf5c45e5b78ec75d6a1ffb4627c271d32051e
  https://github.com/groonga/grnxx/commit/57faf5c45e5b78ec75d6a1ffb4627c271d32051e

  Message:
    Gnx: support GeoPoint.

  Modified files:
    go2/gnx/gnx.cpp
    go2/gnx/gnx.go
    go2/gnx/gnx.h

  Modified: go2/gnx/gnx.cpp (+45 -14)
===================================================================
--- go2/gnx/gnx.cpp    2015-04-08 20:21:55 +0900 (d19a427)
+++ go2/gnx/gnx.cpp    2015-04-09 19:02:26 +0900 (d1feeed)
@@ -35,10 +35,10 @@ gnx_bool gnx_insert_row2(grn_ctx *ctx, grn_obj *table,
       key_size = sizeof(gnx_float);
       break;
     }
-//    case GNX_GEO_POINT: {
-//      key_size = sizeof(gnx_geo_point);
-//      break;
-//    }
+    case GNX_GEO_POINT: {
+      key_size = sizeof(gnx_geo_point);
+      break;
+    }
     case GNX_TEXT: {
       gnx_text text = *static_cast<const gnx_text *>(key);
       key = text.data;
@@ -98,9 +98,12 @@ gnx_bool gnx_set_value2(grn_ctx *ctx, grn_obj *column, gnx_int row_id,
       GRN_FLOAT_SET(ctx, &obj, *static_cast<const gnx_float *>(value));
       break;
     }
-//    case GNX_GEO_POINT: {
-//      break;
-//    }
+    case GNX_GEO_POINT: {
+      gnx_geo_point geo_point = *static_cast<const gnx_geo_point *>(value);
+      GRN_WGS84_GEO_POINT_INIT(&obj, 0);
+      GRN_GEO_POINT_SET(ctx, &obj, geo_point.latitude, geo_point.longitude);
+      break;
+    }
     case GNX_TEXT: {
       gnx_text text = *static_cast<const gnx_text *>(value);
       GRN_TEXT_INIT(&obj, 0);
@@ -185,10 +188,23 @@ gnx_int gnx_insert_rows2(grn_ctx *ctx, grn_obj *table,
       }
       break;
     }
-//    case GNX_GEO_POINT: {
-//      key_size = sizeof(gnx_geo_point);
-//      break;
-//    }
+    case GNX_GEO_POINT: {
+      const gnx_geo_point *geo_point_keys =
+        static_cast<const gnx_geo_point *>(keys);
+      for (gnx_int i = 0; i < num_keys; ++i) {
+        int added;
+        grn_id id = grn_table_add(ctx, table, &geo_point_keys[i],
+                                  sizeof(gnx_geo_point), &added);
+        if (id == GRN_ID_NIL) {
+          row_ids[i] = GNX_NA_INT;
+        } else {
+          row_ids[i] = id;
+          ++count;
+        }
+        inserted[i] = added ? GNX_TRUE : GNX_FALSE;
+      }
+      break;
+    }
     case GNX_TEXT: {
       const gnx_text *text_keys = static_cast<const gnx_text *>(keys);
       for (gnx_int i = 0; i < num_keys; ++i) {
@@ -291,9 +307,24 @@ gnx_int gnx_set_values2(grn_ctx *ctx, grn_obj *table, grn_obj *column,
       GRN_OBJ_FIN(ctx, &obj);
       break;
     }
-//    case GNX_GEO_POINT: {
-//      break;
-//    }
+    case GNX_GEO_POINT: {
+      grn_obj obj;
+      GRN_WGS84_GEO_POINT_INIT(&obj, 0);
+      for (gnx_int i = 0; i < num_values; ++i) {
+        gnx_geo_point value = static_cast<const gnx_geo_point *>(values)[i];
+        GRN_GEO_POINT_SET(ctx, &obj, value.latitude, value.longitude);
+        grn_rc rc = grn_obj_set_value(ctx, column, row_ids[i], &obj,
+                                      GRN_OBJ_SET);
+        if (rc == GRN_SUCCESS) {
+          updated[i] = GNX_TRUE;
+          ++count;
+        } else {
+          updated[i] = GNX_FALSE;
+        }
+      }
+      GRN_OBJ_FIN(ctx, &obj);
+      break;
+    }
     case GNX_TEXT: {
       grn_obj obj;
       GRN_TEXT_INIT(&obj, 0);

  Modified: go2/gnx/gnx.go (+75 -29)
===================================================================
--- go2/gnx/gnx.go    2015-04-08 20:21:55 +0900 (17f96e4)
+++ go2/gnx/gnx.go    2015-04-09 19:02:26 +0900 (d24792c)
@@ -29,15 +29,15 @@ import (
 type Bool uint8
 type Int int64
 type Float float64
-//type GeoPoint struct {
-//	Latitude  int32
-//	Longitude int32
-//}
+type GeoPoint struct {
+	Latitude  int32
+	Longitude int32
+}
 type Text []byte
 type BoolVector []Bool
 type IntVector []Int
 type FloatVector []Float
-//type GeoPointVector []GeoPoint
+type GeoPointVector []GeoPoint
 type TextVector []Text
 
 const (
@@ -58,9 +58,9 @@ func NAInt() Int {
 func NAFloat() Float {
 	return Float(math.NaN())
 }
-//func NAGeoPoint() GeoPoint {
-//	return GeoPoint{math.MinInt32, math.MinInt32}
-//}
+func NAGeoPoint() GeoPoint {
+	return GeoPoint{math.MinInt32, math.MinInt32}
+}
 func NAText() Text {
 	return nil
 }
@@ -73,9 +73,9 @@ func NAIntVector() IntVector {
 func NAFloatVector() FloatVector {
 	return nil
 }
-//func NAGeoPointVector() GeoPointVector {
-//	return nil
-//}
+func NAGeoPointVector() GeoPointVector {
+	return nil
+}
 func NATextVector() TextVector {
 	return nil
 }
@@ -89,9 +89,9 @@ func (this Int) IsNA() bool {
 func (this Float) IsNA() bool {
 	return math.IsNaN(float64(this))
 }
-//func (this GeoPoint) IsNA() bool {
-//	return this.Latitude == math.MinInt32
-//}
+func (this GeoPoint) IsNA() bool {
+	return this.Latitude == math.MinInt32
+}
 func (this Text) IsNA() bool {
 	return this == nil
 }
@@ -104,13 +104,16 @@ func (this IntVector) IsNA() bool {
 func (this FloatVector) IsNA() bool {
 	return this == nil
 }
-//func (this GeoPointVector) IsNA() bool {
-//	return this == nil
-//}
+func (this GeoPointVector) IsNA() bool {
+	return this == nil
+}
 func (this TextVector) IsNA() bool {
 	return this == nil
 }
 
+func (this GeoPoint) MarshalJSON() ([]byte, error) {
+	return []byte(fmt.Sprintf("%dx%d", this.Latitude, this.Longitude)), nil
+}
 func (this Text) MarshalJSON() ([]byte, error) {
 	return json.Marshal(string(this))
 }
@@ -128,6 +131,8 @@ func countColumnarRecords(columnarRecords []interface{}) (int, error) {
 			thisLen = len(values)
 		case []Float:
 			thisLen = len(values)
+		case []GeoPoint:
+			thisLen = len(values)
 		case []Text:
 			thisLen = len(values)
 		case []BoolVector:
@@ -136,6 +141,8 @@ func countColumnarRecords(columnarRecords []interface{}) (int, error) {
 			thisLen = len(values)
 		case []FloatVector:
 			thisLen = len(values)
+		case []GeoPointVector:
+			thisLen = len(values)
 		case []TextVector:
 			thisLen = len(values)
 		default:
@@ -621,6 +628,12 @@ func (db *DB) hashFloat(value Float) int {
 	return int(hasher.Sum32())
 }
 
+func (db *DB) hashGeoPoint(value GeoPoint) int {
+	hasher := fnv.New32a()
+	binary.Write(hasher, binary.LittleEndian, value)
+	return int(hasher.Sum32())
+}
+
 func (db *DB) hashText(value Text) int {
 	hasher := fnv.New32a()
 	hasher.Write([]byte(value))
@@ -635,6 +648,8 @@ func (db *DB) selectGroongaDB(key Valuer) (int, error) {
 		return db.hashInt(value) % len(db.groongaDBs), nil
 	case Float:
 		return db.hashFloat(value) % len(db.groongaDBs), nil
+	case GeoPoint:
+		return db.hashGeoPoint(value) % len(db.groongaDBs), nil
 	case Text:
 		return db.hashText(value) % len(db.groongaDBs), nil
 	}
@@ -806,6 +821,11 @@ func (db *DB) loadC(
 				dbIDs[i] = db.hashFloat(keys[i]) % len(db.groongaDBs)
 				numRecordsPerDBs[dbIDs[i]]++
 			}
+		case []GeoPoint:
+			for i := 0; i < numRecords; i++ {
+				dbIDs[i] = db.hashGeoPoint(keys[i]) % len(db.groongaDBs)
+				numRecordsPerDBs[dbIDs[i]]++
+			}
 		case []Text:
 			for i := 0; i < numRecords; i++ {
 				dbIDs[i] = db.hashText(keys[i]) % len(db.groongaDBs)
@@ -854,6 +874,15 @@ func (db *DB) loadC(
 			for j := 0; j < len(db.groongaDBs); j++ {
 				columnarRecordsPerDBs[j][i] = valuesPerDBs[j]
 			}
+		case []GeoPoint:
+			valuesPerDBs := make([][]GeoPoint, len(db.groongaDBs))
+			for j, value := range values {
+				dbID := dbIDs[j]
+				valuesPerDBs[dbID] = append(valuesPerDBs[dbID], value)
+			}
+			for j := 0; j < len(db.groongaDBs); j++ {
+				columnarRecordsPerDBs[j][i] = valuesPerDBs[j]
+			}
 		case []Text:
 			valuesPerDBs := make([][]Text, len(db.groongaDBs))
 			for j, value := range values {
@@ -890,6 +919,15 @@ func (db *DB) loadC(
 			for j := 0; j < len(db.groongaDBs); j++ {
 				columnarRecordsPerDBs[j][i] = valuesPerDBs[j]
 			}
+		case []GeoPointVector:
+			valuesPerDBs := make([][]GeoPointVector, len(db.groongaDBs))
+			for j, value := range values {
+				dbID := dbIDs[j]
+				valuesPerDBs[dbID] = append(valuesPerDBs[dbID], value)
+			}
+			for j := 0; j < len(db.groongaDBs); j++ {
+				columnarRecordsPerDBs[j][i] = valuesPerDBs[j]
+			}
 		case []TextVector:
 			valuesPerDBs := make([][]TextVector, len(db.groongaDBs))
 			for j, value := range values {
@@ -1048,21 +1086,23 @@ func (db *DB) InsertRow(tableName string, key Valuer) (bool, Int, error) {
 	defer C.free(unsafe.Pointer(cTableName))
 	switch value := key.(type) {
 	case nil:
-		inserted = C.gnx_insert_row(
-			groongaDB.ctx, cTableName, C.GNX_NA, nil, &rowID)
+		inserted = C.gnx_insert_row(groongaDB.ctx, cTableName,
+			C.GNX_NA, nil, &rowID)
 	case Int:
-		inserted = C.gnx_insert_row(
-			groongaDB.ctx, cTableName, C.GNX_INT, unsafe.Pointer(&value), &rowID)
+		inserted = C.gnx_insert_row(groongaDB.ctx, cTableName,
+			C.GNX_INT, unsafe.Pointer(&value), &rowID)
 	case Float:
-		inserted = C.gnx_insert_row(
-			groongaDB.ctx, cTableName, C.GNX_FLOAT, unsafe.Pointer(&value), &rowID)
-//	case GeoPoint:
+		inserted = C.gnx_insert_row(groongaDB.ctx, cTableName,
+			C.GNX_FLOAT, unsafe.Pointer(&value), &rowID)
+	case GeoPoint:
+		inserted = C.gnx_insert_row(groongaDB.ctx, cTableName,
+			C.GNX_GEO_POINT, unsafe.Pointer(&value), &rowID)
 	case Text:
 		cValue := C.CString(string(value))
 		defer C.free(unsafe.Pointer(cValue))
 		text := C.gnx_text{cValue, C.gnx_int(len(value))}
-		inserted = C.gnx_insert_row(
-			groongaDB.ctx, cTableName, C.GNX_TEXT, unsafe.Pointer(&text), &rowID)
+		inserted = C.gnx_insert_row(groongaDB.ctx, cTableName,
+			C.GNX_TEXT, unsafe.Pointer(&text), &rowID)
 	default:
 		return false, NAInt(), fmt.Errorf("unsupported key type")
 	}
@@ -1097,7 +1137,9 @@ func (db *DB) SetValue(tableName string, columnName string, rowID Int,
 	case Float:
 		ok = C.gnx_set_value(groongaDB.ctx, cTableName, cColumnName,
 			C.gnx_int(rowID), C.GNX_FLOAT, unsafe.Pointer(&v))
-//	case GeoPoint:
+	case GeoPoint:
+		ok = C.gnx_set_value(groongaDB.ctx, cTableName, cColumnName,
+			C.gnx_int(rowID), C.GNX_GEO_POINT, unsafe.Pointer(&v))
 	case Text:
 		cValue := C.CString(string(v))
 		defer C.free(unsafe.Pointer(cValue))
@@ -1158,7 +1200,9 @@ func (db *DB) InsertRow2(table *Table, key Valuer) (bool, Int, error) {
 	case Float:
 		inserted = C.gnx_insert_row2(groongaDB.ctx, groongaTable.obj,
 			C.GNX_FLOAT, unsafe.Pointer(&value), &rowID)
-//	case GeoPoint:
+	case GeoPoint:
+		inserted = C.gnx_insert_row2(groongaDB.ctx, groongaTable.obj,
+			C.GNX_GEO_POINT, unsafe.Pointer(&value), &rowID)
 	case Text:
 		cValue := C.CString(string(value))
 		defer C.free(unsafe.Pointer(cValue))
@@ -1195,7 +1239,9 @@ func (db *DB) SetValue2(column *Column, rowID Int, value Valuer) error {
 	case Float:
 		ok = C.gnx_set_value2(groongaDB.ctx, groongaColumn.obj,
 			C.gnx_int(rowID), C.GNX_FLOAT, unsafe.Pointer(&v))
-//	case GeoPoint:
+	case GeoPoint:
+		ok = C.gnx_set_value2(groongaDB.ctx, groongaColumn.obj,
+			C.gnx_int(rowID), C.GNX_GEO_POINT, unsafe.Pointer(&v))
 	case Text:
 		cValue := C.CString(string(v))
 		defer C.free(unsafe.Pointer(cValue))

  Modified: go2/gnx/gnx.h (+5 -1)
===================================================================
--- go2/gnx/gnx.h    2015-04-08 20:21:55 +0900 (aa07695)
+++ go2/gnx/gnx.h    2015-04-09 19:02:26 +0900 (ede8985)
@@ -20,7 +20,11 @@ typedef enum gnx_data_type {
 typedef uint8_t gnx_bool;
 typedef int64_t gnx_int;
 typedef double gnx_float;
-//typedef gnx_geo_point struct { int32_t latitude; int32_t longitude; };
+//typedef grn_geo_point gnx_geo_point;
+typedef struct {
+  int32_t latitude;
+  int32_t longitude;
+} gnx_geo_point;
 typedef struct {
   const char *data;
   gnx_int size;
-------------- next part --------------
HTML����������������������������...
Descargar 



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