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