[Groonga-commit] groonga/grnxx at 5ab5269 [master] Add IndexRange that is used to enumerate records in range.

Back to archive index

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 



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