susumu.yata
null+****@clear*****
Tue Sep 9 13:10:45 JST 2014
susumu.yata 2014-09-09 13:10:45 +0900 (Tue, 09 Sep 2014) New Revision: 5ab526943104aa94d16ec52678b8719850a96fc9 https://github.com/groonga/grnxx/commit/5ab526943104aa94d16ec52678b8719850a96fc9 Message: Add IndexRange that is used to enumerate records in range. Modified files: include/grnxx/index.hpp lib/grnxx/index.cpp lib/grnxx/tree_index.hpp Modified: include/grnxx/index.hpp (+61 -0) =================================================================== --- include/grnxx/index.hpp 2014-09-09 11:02:25 +0900 (fa73b66) +++ include/grnxx/index.hpp 2014-09-09 13:10:45 +0900 (0af162b) @@ -1,11 +1,71 @@ #ifndef GRNXX_INDEX_HPP #define GRNXX_INDEX_HPP +#include "grnxx/datum.hpp" #include "grnxx/name.hpp" #include "grnxx/types.hpp" namespace grnxx { +enum EndPointType { + INCLUSIVE_END_POINT, + EXCLUSIVE_END_POINT +}; + +struct EndPoint { + Datum value; + EndPointType type; +}; + +class IndexRange { + public: + IndexRange() + : has_lower_bound_(false), + has_upper_bound_(false), + lower_bound_(), + upper_bound_() {} + + bool has_lower_bound() const { + return has_lower_bound_; + } + bool has_upper_bound() const { + return has_upper_bound_; + } + + const EndPoint &lower_bound() const { + return lower_bound_; + } + const EndPoint &upper_bound() const { + return upper_bound_; + } + + void set_lower_bound(const Datum &value, + EndPointType type = INCLUSIVE_END_POINT) { + has_lower_bound_ = true; + lower_bound_.value = value; + lower_bound_.type = type; + } + void set_upper_bound(const Datum &value, + EndPointType type = INCLUSIVE_END_POINT) { + has_upper_bound_ = true; + upper_bound_.value = value; + upper_bound_.type = type; + } + + void unset_lower_bound() { + has_lower_bound_ = false; + } + void unset_upper_bound() { + has_lower_bound_ = false; + } + + private: + bool has_lower_bound_; + bool has_upper_bound_; + EndPoint lower_bound_; + EndPoint upper_bound_; +}; + class Index { public: virtual ~Index(); @@ -30,6 +90,7 @@ class Index { // "error" != nullptr. virtual unique_ptr<Cursor> create_cursor( Error *error, + const IndexRange &range = IndexRange(), const CursorOptions &options = CursorOptions()) const; // Insert a new entry. Modified: lib/grnxx/index.cpp (+44 -2) =================================================================== --- lib/grnxx/index.cpp 2014-09-09 11:02:25 +0900 (7f4471d) +++ lib/grnxx/index.cpp 2014-09-09 13:10:45 +0900 (d9d6225) @@ -15,6 +15,7 @@ Index::~Index() {} unique_ptr<Cursor> Index::create_cursor( Error *error, + const IndexRange &range, const CursorOptions &options) const { GRNXX_ERROR_SET(error, NOT_SUPPORTED_YET, "Not supoprted yet"); return nullptr; @@ -179,10 +180,51 @@ TreeIndex<Int>::~TreeIndex() {} unique_ptr<Cursor> TreeIndex<Int>::create_cursor( Error *error, + const IndexRange &range, const CursorOptions &options) const { + Int lower_bound_value = numeric_limits<Int>::min(); + if (range.has_lower_bound()) { + const EndPoint &lower_bound = range.lower_bound(); + if (lower_bound.value.type() != INT_DATA) { + GRNXX_ERROR_SET(error, INVALID_ARGUMENT, "Data type conflict"); + return nullptr; + } + lower_bound_value = lower_bound.value.force_int(); + if (lower_bound.type == EXCLUSIVE_END_POINT) { + if (lower_bound_value == numeric_limits<Int>::max()) { + // TODO: Invalid range. + return nullptr; + } + ++lower_bound_value; + } + } + + Int upper_bound_value = numeric_limits<Int>::max(); + if (range.has_upper_bound()) { + const EndPoint &upper_bound = range.upper_bound(); + if (upper_bound.value.type() != INT_DATA) { + GRNXX_ERROR_SET(error, INVALID_ARGUMENT, "Data type conflict"); + return nullptr; + } + upper_bound_value = upper_bound.value.force_int(); + if (upper_bound.type == EXCLUSIVE_END_POINT) { + if (upper_bound_value == numeric_limits<Int>::min()) { + // TODO: Invalid range. + return nullptr; + } + --upper_bound_value; + } + } + + if (lower_bound_value > upper_bound_value) { + // TODO: Invalid range. + return nullptr; + } + + auto begin = map_.lower_bound(lower_bound_value); + auto end = map_.upper_bound(upper_bound_value); unique_ptr<Cursor> cursor( - new (nothrow) TreeIndexCursor<Int>(column_->table(), - map_.begin(), map_.end())); + new (nothrow) TreeIndexCursor<Int>(column_->table(), begin, end)); if (!cursor) { GRNXX_ERROR_SET(error, NO_MEMORY, "Memory allocation failed"); return nullptr; Modified: lib/grnxx/tree_index.hpp (+2 -1) =================================================================== --- lib/grnxx/tree_index.hpp 2014-09-09 11:02:25 +0900 (adb807e) +++ lib/grnxx/tree_index.hpp 2014-09-09 13:10:45 +0900 (c126b53) @@ -28,7 +28,8 @@ class TreeIndex<Int> : public Index { unique_ptr<Cursor> create_cursor( Error *error, - const CursorOptions &options = CursorOptions()) const; + const IndexRange &range, + const CursorOptions &options) const; bool insert(Error *error, Int row_id, const Datum &value); bool remove(Error *error, Int row_id, const Datum &value); -------------- next part -------------- HTML����������������������������...Download