[Groonga-commit] groonga/groonga at 6c6eb6c [master] egn: support a Bool vector column as an output column

Back to archive index

susumu.yata null+****@clear*****
Wed Jul 8 10:40:35 JST 2015


susumu.yata	2015-07-08 10:40:35 +0900 (Wed, 08 Jul 2015)

  New Revision: 6c6eb6ca8afbbe1db8feac1c848e037a9cf9c1c5
  https://github.com/groonga/groonga/commit/6c6eb6ca8afbbe1db8feac1c848e037a9cf9c1c5

  Message:
    egn: support a Bool vector column as an output column

  Modified files:
    lib/egn.cpp
    lib/grn_egn.h
    lib/grn_egn.hpp

  Modified: lib/egn.cpp (+169 -3)
===================================================================
--- lib/egn.cpp    2015-07-08 12:17:02 +0900 (21834ae)
+++ lib/egn.cpp    2015-07-08 10:40:35 +0900 (78406fe)
@@ -615,6 +615,52 @@ class ConstantNode<Text> : public TypedNode<Text> {
     : TypedNode<Text>(), value_(value), value_buf_() {}
 };
 
+// -- ConstantNode<BoolVector> --
+
+template <>
+class ConstantNode<BoolVector> : public TypedNode<BoolVector> {
+ public:
+  ~ConstantNode() {}
+
+  static grn_rc open(const BoolVector &value, ExpressionNode **node) {
+    ConstantNode *new_node = new (std::nothrow) ConstantNode(value);
+    if (!new_node) {
+      return GRN_NO_MEMORY_AVAILABLE;
+    }
+    try {
+      new_node->value_buf_.resize(value.raw.size);
+    } catch (const std::bad_alloc &) {
+      delete new_node;
+      return GRN_NO_MEMORY_AVAILABLE;
+    }
+    std::memcpy(&*new_node->value_buf_.begin(), value.raw.ptr,
+                sizeof(grn_egn_bool) * value.raw.size);
+    new_node->value_.raw.ptr = &*new_node->value_buf_.begin();
+    *node = new_node;
+    return GRN_SUCCESS;
+  }
+
+  ExpressionNodeType type() const {
+    return GRN_EGN_CONSTANT_NODE;
+  }
+
+  grn_rc evaluate(
+    const Record *records, size_t num_records, BoolVector *results) {
+    for (size_t i = 0; i < num_records; ++i) {
+      results[i] = value_;
+    }
+    return GRN_SUCCESS;
+  }
+
+ private:
+  grn_builtin_type builtin_type_;
+  BoolVector value_;
+  std::vector<grn_egn_bool> value_buf_;
+
+  explicit ConstantNode(const BoolVector &value)
+    : TypedNode<BoolVector>(), value_(value), value_buf_() {}
+};
+
 // -- ColumnNode --
 
 template <typename T>
@@ -1049,6 +1095,67 @@ grn_rc ColumnNode<GeoPoint>::evaluate(
   return GRN_SUCCESS;
 }
 
+// -- ColumnNode<BoolVector> --
+
+template <>
+class ColumnNode<BoolVector> : public TypedNode<BoolVector> {
+ public:
+  ~ColumnNode() {
+    GRN_OBJ_FIN(ctx_, &buf_);
+  }
+
+  static grn_rc open(grn_ctx *ctx, grn_obj *column, ExpressionNode **node) {
+    ColumnNode *new_node = new (std::nothrow) ColumnNode(ctx, column);
+    if (!new_node) {
+      return GRN_NO_MEMORY_AVAILABLE;
+    }
+    *node = new_node;
+    return GRN_SUCCESS;
+  }
+
+  ExpressionNodeType type() const {
+    return GRN_EGN_COLUMN_NODE;
+  }
+  grn_builtin_type builtin_type() const {
+    return static_cast<grn_builtin_type>(grn_obj_get_range(ctx_, column_));
+  }
+
+  grn_rc evaluate(
+    const Record *records, size_t num_records, BoolVector *results);
+
+ private:
+  grn_ctx *ctx_;
+  grn_obj *column_;
+  grn_obj buf_;
+
+  ColumnNode(grn_ctx *ctx, grn_obj *column)
+    : TypedNode<BoolVector>(), ctx_(ctx), column_(column), buf_() {
+    GRN_BOOL_INIT(&buf_, GRN_OBJ_VECTOR);
+  }
+};
+
+grn_rc ColumnNode<BoolVector>::evaluate(
+  const Record *records, size_t num_records, BoolVector *results) {
+  GRN_BULK_REWIND(&buf_);
+  size_t offset = 0;
+  for (size_t i = 0; i < num_records; i++) {
+    grn_obj_get_value(ctx_, column_, records[i].id, &buf_);
+    if (ctx_->rc != GRN_SUCCESS) {
+      return ctx_->rc;
+    }
+    size_t next_size = GRN_BULK_VSIZE(&buf_);
+    size_t next_offset = next_size / sizeof(grn_egn_bool);
+    results[i].raw.size = next_offset - offset;
+    offset = next_offset;
+  }
+  grn_egn_bool *ptr = reinterpret_cast<grn_egn_bool *>(GRN_BULK_HEAD(&buf_));
+  for (size_t i = 0; i < num_records; i++) {
+    results[i].raw.ptr = ptr;
+    ptr += results[i].raw.size;
+  }
+  return GRN_SUCCESS;
+}
+
 // -- OperatorNode --
 
 template <typename T>
@@ -2341,7 +2448,7 @@ grn_rc Expression::push_object(grn_obj *obj) {
       return GRN_INVALID_ARGUMENT;
     }
     case GRN_VECTOR: {
-      // FIXME: To be supported.
+      rc = push_vector_object(obj);
       return GRN_INVALID_ARGUMENT;
     }
     case GRN_ACCESSOR: {
@@ -2701,6 +2808,32 @@ grn_rc Expression::push_bulk_object(grn_obj *obj) {
   return rc;
 }
 
+grn_rc Expression::push_vector_object(grn_obj *obj) {
+  grn_rc rc;
+  ExpressionNode *node;
+  grn_builtin_type builtin_type =
+    static_cast<grn_builtin_type>(obj->header.domain);
+  switch (builtin_type) {
+    case GRN_DB_BOOL: {
+      BoolVector value;
+      value.raw.ptr = reinterpret_cast<grn_egn_bool *>(GRN_BULK_HEAD(obj));
+      value.raw.size = GRN_BULK_VSIZE(obj) / sizeof(grn_egn_bool);
+      rc = ConstantNode<BoolVector>::open(value, &node);
+      break;
+    }
+    default: {
+      return GRN_INVALID_ARGUMENT;
+    }
+  }
+  if (rc == GRN_SUCCESS) try {
+    stack_.push_back(node);
+  } catch (const std::bad_alloc &) {
+    delete node;
+    return GRN_NO_MEMORY_AVAILABLE;
+  }
+  return rc;
+}
+
 grn_rc Expression::push_column_object(grn_obj *obj) {
   grn_obj *owner_table = grn_column_table(ctx_, obj);
   if (owner_table != table_) {
@@ -2765,7 +2898,16 @@ grn_rc Expression::push_column_object(grn_obj *obj) {
           break;
         }
         case GRN_OBJ_COLUMN_VECTOR: {
-          return GRN_OPERATION_NOT_SUPPORTED;
+          switch (range) {
+            case GRN_DB_BOOL: {
+              rc = ColumnNode<BoolVector>::open(ctx_, obj, &node);
+              break;
+            }
+            default: {
+              return GRN_INVALID_ARGUMENT;
+            }
+          }
+          break;
         }
         default: {
           return GRN_INVALID_ARGUMENT;
@@ -3149,7 +3291,8 @@ grn_egn_select_output(grn_ctx *ctx, grn_obj *table,
     GRN_TEXT_PUT(ctx, ctx->impl->outbuf, names[i].data(), names[i].size());
     GRN_TEXT_PUT(ctx, ctx->impl->outbuf, "\",\"", 3);
     switch (expressions[i]->data_type()) {
-      case GRN_EGN_BOOL: {
+      case GRN_EGN_BOOL:
+      case GRN_EGN_BOOL_VECTOR: {
         GRN_TEXT_PUTS(ctx, ctx->impl->outbuf, "Bool");
         break;
       }
@@ -3295,6 +3438,12 @@ grn_egn_select_output(grn_ctx *ctx, grn_obj *table,
                                      (grn::egn::GeoPoint *)&bufs[i][0]);
             break;
           }
+          case GRN_EGN_BOOL_VECTOR: {
+            bufs[i].resize(sizeof(grn_egn_bool_vector) * batch_size);
+            expressions[i]->evaluate(records + count, batch_size,
+                                     (grn::egn::BoolVector *)&bufs[i][0]);
+            break;
+          }
           default: {
             break;
           }
@@ -3345,6 +3494,23 @@ grn_egn_select_output(grn_ctx *ctx, grn_obj *table,
               GRN_TEXT_PUTC(ctx, ctx->impl->outbuf, '"');
               break;
             }
+            case GRN_EGN_BOOL_VECTOR: {
+              GRN_TEXT_PUTC(ctx, ctx->impl->outbuf, '[');
+              grn_egn_bool_vector value =
+                ((grn_egn_bool_vector *)&bufs[j][0])[i];
+              for (size_t k = 0; k < value.size; ++k) {
+                if (k != 0) {
+                  GRN_TEXT_PUTC(ctx, ctx->impl->outbuf, ',');
+                }
+                if (value.ptr[k]) {
+                  GRN_TEXT_PUT(ctx, ctx->impl->outbuf, "true", 4);
+                } else {
+                  GRN_TEXT_PUT(ctx, ctx->impl->outbuf, "false", 5);
+                }
+              }
+              GRN_TEXT_PUTC(ctx, ctx->impl->outbuf, ']');
+              break;
+            }
             default: {
               break;
             }

  Modified: lib/grn_egn.h (+24 -0)
===================================================================
--- lib/grn_egn.h    2015-07-08 12:17:02 +0900 (09b1e4e)
+++ lib/grn_egn.h    2015-07-08 10:40:35 +0900 (55ad06c)
@@ -91,6 +91,30 @@ typedef struct {
   size_t size;
 } grn_egn_text;
 typedef grn_geo_point grn_egn_geo_point;
+typedef struct {
+  const grn_egn_bool *ptr;
+  size_t size;
+} grn_egn_bool_vector;
+//typedef struct {
+//  const grn_egn_int *ptr;
+//  size_t size;
+//} grn_egn_int_vector;
+//typedef struct {
+//  const grn_egn_float *ptr;
+//  size_t size;
+//} grn_egn_float_vector;
+//typedef struct {
+//  const grn_egn_time *ptr;
+//  size_t size;
+//} grn_egn_time_vector;
+//typedef struct {
+//  const grn_egn_text *ptr;
+//  size_t size;
+//} grn_egn_text_vector;
+//typedef struct {
+//  const grn_egn_geo_point *ptr;
+//  size_t size;
+//} grn_egn_geo_point_vector;
 
 /*
  * grn_egn_select() finds records passing through a filter (specified by

  Modified: lib/grn_egn.hpp (+110 -0)
===================================================================
--- lib/grn_egn.hpp    2015-07-08 12:17:02 +0900 (733ac35)
+++ lib/grn_egn.hpp    2015-07-08 10:40:35 +0900 (657fc9c)
@@ -212,6 +212,115 @@ inline bool operator!=(GeoPoint lhs, GeoPoint rhs) {
          (lhs.raw.longitude != rhs.raw.longitude);
 }
 
+struct BoolVector {
+  typedef grn_egn_bool_vector Raw;
+  Raw raw;
+
+  static DataType data_type() {
+    return GRN_EGN_BOOL_VECTOR;
+  }
+  static grn_builtin_type default_builtin_type() {
+    return GRN_DB_BOOL;
+  }
+
+  BoolVector() : raw() {}
+  BoolVector(const BoolVector &value) : raw(value.raw) {}
+  explicit BoolVector(const Raw &value) : raw(value) {}
+  BoolVector(const grn_egn_bool *ptr, size_t size) : raw((Raw){ptr, size}) {}
+  ~BoolVector() {}
+};
+
+//struct IntVector {
+//  typedef grn_egn_int_vector Raw;
+//  Raw raw;
+
+//  static DataType data_type() {
+//    return GRN_EGN_INT_VECTOR;
+//  }
+//  static grn_builtin_type default_builtin_type() {
+//    return GRN_DB_INT64;
+//  }
+
+//  IntVector() : raw() {}
+//  IntVector(const IntVector &value) : raw(value.raw) {}
+//  explicit IntVector(const Raw &value) : raw(value) {}
+//  IntVector(const grn_egn_int *ptr, size_t size) : raw((Raw){ptr, size}) {}
+//  ~IntVector() {}
+//};
+
+//struct FloatVector {
+//  typedef grn_egn_float_vector Raw;
+//  Raw raw;
+
+//  static DataType data_type() {
+//    return GRN_EGN_FLOAT_VECTOR;
+//  }
+//  static grn_builtin_type default_builtin_type() {
+//    return GRN_DB_FLOAT;
+//  }
+
+//  FloatVector() : raw() {}
+//  FloatVector(const FloatVector &value) : raw(value.raw) {}
+//  explicit FloatVector(const Raw &value) : raw(value) {}
+//  FloatVector(const grn_egn_float *ptr, size_t size) : raw((Raw){ptr, size}) {}
+//  ~FloatVector() {}
+//};
+
+//struct TimeVector {
+//  typedef grn_egn_time_vector Raw;
+//  Raw raw;
+
+//  static DataType data_type() {
+//    return GRN_EGN_INT_VECTOR;
+//  }
+//  static grn_builtin_type default_builtin_type() {
+//    return GRN_DB_INT64;
+//  }
+
+//  TimeVector() : raw() {}
+//  TimeVector(const TimeVector &value) : raw(value.raw) {}
+//  explicit TimeVector(const Raw &value) : raw(value) {}
+//  TimeVector(const grn_egn_time *ptr, size_t size) : raw((Raw){ptr, size}) {}
+//  ~TimeVector() {}
+//};
+
+//struct TextVector {
+//  typedef grn_egn_text_vector Raw;
+//  Raw raw;
+
+//  static DataType data_type() {
+//    return GRN_EGN_TEXT_VECTOR;
+//  }
+//  static grn_builtin_type default_builtin_type() {
+//    return GRN_DB_TEXT;
+//  }
+
+//  TextVector() : raw() {}
+//  TextVector(const TextVector &value) : raw(value.raw) {}
+//  explicit TextVector(const Raw &value) : raw(value) {}
+//  TextVector(const grn_egn_text *ptr, size_t size) : raw((Raw){ptr, size}) {}
+//  ~TextVector() {}
+//};
+
+//struct GeoPointVector {
+//  typedef grn_egn_geo_point_vector Raw;
+//  Raw raw;
+
+//  static DataType data_type() {
+//    return GRN_EGN_GEO_POINT_VECTOR;
+//  }
+//  static grn_builtin_type default_builtin_type() {
+//    return GRN_DB_VOID;
+//  }
+
+//  GeoPointVector() : raw() {}
+//  GeoPointVector(const GeoPointVector &value) : raw(value.raw) {}
+//  explicit GeoPointVector(const Raw &value) : raw(value) {}
+//  GeoPointVector(const grn_egn_geo_point *ptr, size_t size)
+//    : raw((Raw){ptr, size}) {}
+//  ~GeoPointVector() {}
+//};
+
 // Cursor is a base class which provides an interface for sequential access to
 // records.
 class Cursor {
@@ -277,6 +386,7 @@ class Expression {
   void update_types();
 
   grn_rc push_bulk_object(grn_obj *obj);
+  grn_rc push_vector_object(grn_obj *obj);
   grn_rc push_column_object(grn_obj *obj);
 
   grn_rc create_unary_node(OperatorType operator_type,
-------------- next part --------------
HTML����������������������������...
Télécharger 



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