[Groonga-commit] groonga/groonga at 2b2c78c [master] egn: support a Text vector column as an output column

Back to archive index

susumu.yata null+****@clear*****
Wed Jul 8 16:21:10 JST 2015


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

  New Revision: 2b2c78cfda1597804ca6770111dcd2584fd4d3e6
  https://github.com/groonga/groonga/commit/2b2c78cfda1597804ca6770111dcd2584fd4d3e6

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

  Modified files:
    lib/egn.cpp

  Modified: lib/egn.cpp (+102 -1)
===================================================================
--- lib/egn.cpp    2015-07-08 16:08:44 +0900 (e131755)
+++ lib/egn.cpp    2015-07-08 16:21:10 +0900 (7a19aa6)
@@ -1480,6 +1480,80 @@ grn_rc ColumnNode<TimeVector>::evaluate(
   return GRN_SUCCESS;
 }
 
+// -- ColumnNode<TextVector> --
+
+template <>
+class ColumnNode<TextVector> : public TypedNode<TextVector> {
+ 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, TextVector *results);
+
+ private:
+  grn_ctx *ctx_;
+  grn_obj *column_;
+  grn_obj buf_;
+  std::vector<grn_egn_text> refs_;
+
+  ColumnNode(grn_ctx *ctx, grn_obj *column)
+    : TypedNode<TextVector>(), ctx_(ctx), column_(column), buf_(), refs_() {
+    GRN_TEXT_INIT(&buf_, GRN_OBJ_VECTOR);
+  }
+};
+
+grn_rc ColumnNode<TextVector>::evaluate(
+  const Record *records, size_t num_records, TextVector *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_offset = grn_vector_size(ctx_, &buf_);
+    results[i].raw.size = next_offset - offset;
+    offset = next_offset;
+  }
+  try {
+    refs_.resize(offset);
+  } catch (const std::bad_alloc &) {
+    return GRN_NO_MEMORY_AVAILABLE;
+  }
+  offset = 0;
+  size_t total = 0;
+  for (size_t i = 0; i < num_records; i++) {
+    size_t partial_total = 0;
+    for (size_t j = 0; j < results[i].raw.size; ++j) {
+      refs_[offset + j].size = grn_vector_get_element(
+        ctx_, &buf_, offset + j, &refs_[offset + j].ptr, NULL, NULL);
+      partial_total += refs_[offset + j].size;
+    }
+    total += partial_total;
+    results[i].raw.ptr = &*refs_.begin() + offset;
+    offset += results[i].raw.size;
+  }
+  return GRN_SUCCESS;
+}
+
 // -- ColumnNode<GeoPointVector> --
 
 template <>
@@ -3312,6 +3386,12 @@ grn_rc Expression::push_column_object(grn_obj *obj) {
               rc = ColumnNode<TimeVector>::open(ctx_, obj, &node);
               break;
             }
+            case GRN_DB_SHORT_TEXT:
+            case GRN_DB_TEXT:
+            case GRN_DB_LONG_TEXT: {
+              rc = ColumnNode<TextVector>::open(ctx_, obj, &node);
+              break;
+            }
             case GRN_DB_TOKYO_GEO_POINT:
             case GRN_DB_WGS84_GEO_POINT: {
               rc = ColumnNode<GeoPointVector>::open(ctx_, obj, &node);
@@ -3762,7 +3842,8 @@ grn_egn_select_output(grn_ctx *ctx, grn_obj *table,
         GRN_TEXT_PUTS(ctx, ctx->impl->outbuf, "Time");
         break;
       }
-      case GRN_EGN_TEXT: {
+      case GRN_EGN_TEXT:
+      case GRN_EGN_TEXT_VECTOR: {
         switch (expressions[i]->builtin_type()) {
           case GRN_DB_SHORT_TEXT: {
             GRN_TEXT_PUTS(ctx, ctx->impl->outbuf, "ShortText");
@@ -3880,6 +3961,12 @@ grn_egn_select_output(grn_ctx *ctx, grn_obj *table,
                                      (grn::egn::TimeVector *)&bufs[i][0]);
             break;
           }
+          case GRN_EGN_TEXT_VECTOR: {
+            bufs[i].resize(sizeof(grn_egn_text_vector) * batch_size);
+            expressions[i]->evaluate(records + count, batch_size,
+                                     (grn::egn::TextVector *)&bufs[i][0]);
+            break;
+          }
           case GRN_EGN_GEO_POINT_VECTOR: {
             bufs[i].resize(sizeof(grn_egn_geo_point_vector) * batch_size);
             expressions[i]->evaluate(records + count, batch_size,
@@ -3992,6 +4079,20 @@ grn_egn_select_output(grn_ctx *ctx, grn_obj *table,
               GRN_TEXT_PUTC(ctx, ctx->impl->outbuf, ']');
               break;
             }
+            case GRN_EGN_TEXT_VECTOR: {
+              GRN_TEXT_PUTC(ctx, ctx->impl->outbuf, '[');
+              grn_egn_text_vector value =
+                ((grn_egn_text_vector *)&bufs[j][0])[i];
+              for (size_t k = 0; k < value.size; ++k) {
+                if (k != 0) {
+                  GRN_TEXT_PUTC(ctx, ctx->impl->outbuf, ',');
+                }
+                grn_text_esc(ctx, ctx->impl->outbuf, value.ptr[k].ptr,
+                             value.ptr[k].size);
+              }
+              GRN_TEXT_PUTC(ctx, ctx->impl->outbuf, ']');
+              break;
+            }
             case GRN_EGN_GEO_POINT_VECTOR: {
               GRN_TEXT_PUTC(ctx, ctx->impl->outbuf, '[');
               grn_egn_geo_point_vector value =
-------------- next part --------------
HTML����������������������������...
다운로드 



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