[Groonga-commit] groonga/grnxx at b505976 [master] Enable map cursors.

Back to archive index

susumu.yata null+****@clear*****
Mon May 27 16:09:08 JST 2013


susumu.yata	2013-05-27 16:09:08 +0900 (Mon, 27 May 2013)

  New Revision: b5059763d728898f3f44c7edb45469ec3b721f4a
  https://github.com/groonga/grnxx/commit/b5059763d728898f3f44c7edb45469ec3b721f4a

  Message:
    Enable map cursors.

  Modified files:
    lib/grnxx/map.cpp
    lib/grnxx/map.hpp
    lib/grnxx/map/cursor_impl.cpp
    lib/grnxx/map/cursor_impl.hpp
    lib/grnxx/map_cursor_query.hpp

  Modified: lib/grnxx/map.cpp (+14 -13)
===================================================================
--- lib/grnxx/map.cpp    2013-05-27 15:58:28 +0900 (e4f112d)
+++ lib/grnxx/map.cpp    2013-05-27 16:09:08 +0900 (697b4d6)
@@ -247,25 +247,26 @@ bool Map<T>::truncate() {
 }
 
 template <typename T>
-MapCursor<T> *Map<T>::create_cursor(MapCursorAll<T>,
-                                    const MapCursorOptions &) {
-  // TODO: Give a naive implementation.
-  GRNXX_ERROR() << "invalid operation";
-  return nullptr;
+MapCursor<T> *Map<T>::create_cursor(MapCursorAllKeys<T>,
+                                    const MapCursorOptions &options) {
+  return map::AllKeysCursor<T>::create(this, options);
 }
 
 template <typename T>
-MapCursor<T> *Map<T>::create_cursor(const MapCursorKeyIDRange<T> &,
-                                    const MapCursorOptions &) {
-  // TODO: Give a naive implementation.
-  GRNXX_ERROR() << "invalid operation";
-  return nullptr;
+MapCursor<T> *Map<T>::create_cursor(const MapCursorKeyIDRange<T> &query,
+                                    const MapCursorOptions &options) {
+  return map::KeyIDRangeCursor<T>::create(this, query, options);
 }
 
 template <typename T>
-MapCursor<T> *Map<T>::create_cursor(const MapCursorKeyRange<T> &,
-                                    const MapCursorOptions &) {
-  // TODO: Give a naive implementation.
+MapCursor<T> *Map<T>::create_cursor(const MapCursorKeyRange<T> &query,
+                                    const MapCursorOptions &options) {
+  return map::KeyRangeCursor<T>::create(this, query, options);
+}
+
+template <>
+MapCursor<GeoPoint> *Map<GeoPoint>::create_cursor(
+    const MapCursorKeyRange<GeoPoint> &, const MapCursorOptions &) {
   GRNXX_ERROR() << "invalid operation";
   return nullptr;
 }

  Modified: lib/grnxx/map.hpp (+3 -3)
===================================================================
--- lib/grnxx/map.hpp    2013-05-27 15:58:28 +0900 (e99fada)
+++ lib/grnxx/map.hpp    2013-05-27 16:09:08 +0900 (bada395)
@@ -129,8 +129,8 @@ class Map {
 
   // TODO: Not yet fixed.
   // Return a reference to create a cursor query.
-  MapCursorAll<T> all() const {
-    return MapCursorAll<T>();
+  MapCursorAllKeys<T> all_keys() const {
+    return MapCursorAllKeys<T>();
   }
   // Return a reference to create a cursor query.
   MapCursorKeyID<T> key_id() const {
@@ -143,7 +143,7 @@ class Map {
 
   // Create a cursor for accessing all the keys.
   virtual Cursor *create_cursor(
-      MapCursorAll<T> query,
+      MapCursorAllKeys<T> query,
       const MapCursorOptions &options = MapCursorOptions());
   // Create a cursor for accessing keys that satisfy "query".
   virtual Cursor *create_cursor(

  Modified: lib/grnxx/map/cursor_impl.cpp (+93 -0)
===================================================================
--- lib/grnxx/map/cursor_impl.cpp    2013-05-27 15:58:28 +0900 (e8c681f)
+++ lib/grnxx/map/cursor_impl.cpp    2013-05-27 16:09:08 +0900 (f99fecc)
@@ -29,6 +29,86 @@ namespace grnxx {
 namespace map {
 
 template <typename T>
+AllKeysCursor<T>::AllKeysCursor()
+    : MapCursor<T>(), map_(), cur_(), end_(), step_(), count_(0), options_() {}
+
+template <typename T>
+AllKeysCursor<T>::~AllKeysCursor() {}
+
+template <typename T>
+AllKeysCursor<T> *AllKeysCursor<T>::create(
+    Map<T> *map, const MapCursorOptions &options) {
+  std::unique_ptr<AllKeysCursor<T>> cursor(
+      new (std::nothrow) AllKeysCursor<T>);
+  if (!cursor) {
+    GRNXX_ERROR() << "new grnxx::map::AllKeysCursor<T> failed";
+    return nullptr;
+  }
+  if (!cursor->init(map, options)) {
+    return nullptr;
+  }
+  return cursor.release();
+}
+
+template <typename T>
+bool AllKeysCursor<T>::next() {
+  if (count_ >= options_.limit) {
+    return false;
+  }
+  while (cur_ != end_) {
+    cur_ += step_;
+    if (map_->get(cur_, &this->key_)) {
+      this->key_id_ = cur_;
+      ++count_;
+      return true;
+    }
+  }
+  return false;
+}
+
+template <typename T>
+bool AllKeysCursor<T>::remove() {
+  return map_->unset(this->key_id_);
+}
+
+template <typename T>
+bool AllKeysCursor<T>::init(Map<T> *map, const MapCursorOptions &options) {
+  map_ = map;
+  options_ = options;
+  options_.flags = MAP_CURSOR_ORDER_BY_ID;
+  if (options.flags & MAP_CURSOR_REVERSE_ORDER) {
+    options_.flags |= MAP_CURSOR_REVERSE_ORDER;
+  }
+
+  const int64_t min = map->min_key_id();
+  const int64_t max = map->max_key_id();
+  if (min > max) {
+    // There are no keys in the range [min, max].
+    cur_ = end_ = 0;
+    return true;
+  }
+
+  if (options_.flags & MAP_CURSOR_REVERSE_ORDER) {
+    cur_ = max + 1;
+    end_ = min;
+    step_ = -1;
+  } else {
+    cur_ = min - 1;
+    end_ = max;
+    step_ = 1;
+  }
+
+  // Skip the first "options_.offset" keys in range.
+  for (uint64_t count = 0; (count < options_.offset) && (cur_ != end_); ) {
+    cur_ += step_;
+    if (map_->get(cur_)) {
+      ++count;
+    }
+  }
+  return true;
+}
+
+template <typename T>
 KeyIDRangeCursor<T>::KeyIDRangeCursor()
     : MapCursor<T>(), map_(), cur_(), end_(), step_(), count_(0),
       query_(), options_() {}
@@ -238,6 +318,19 @@ bool KeyRangeCursor<T>::filter(KeyArg key) const {
   return true;
 }
 
+template class AllKeysCursor<int8_t>;
+template class AllKeysCursor<int16_t>;
+template class AllKeysCursor<int32_t>;
+template class AllKeysCursor<int64_t>;
+template class AllKeysCursor<uint8_t>;
+template class AllKeysCursor<uint16_t>;
+template class AllKeysCursor<uint32_t>;
+template class AllKeysCursor<uint64_t>;
+template class AllKeysCursor<double>;
+template class AllKeysCursor<GeoPoint>;
+// TODO: To be enabled.
+//template class AllKeysCursor<Bytes>;
+
 template class KeyIDRangeCursor<int8_t>;
 template class KeyIDRangeCursor<int16_t>;
 template class KeyIDRangeCursor<int32_t>;

  Modified: lib/grnxx/map/cursor_impl.hpp (+25 -0)
===================================================================
--- lib/grnxx/map/cursor_impl.hpp    2013-05-27 15:58:28 +0900 (77efc86)
+++ lib/grnxx/map/cursor_impl.hpp    2013-05-27 16:09:08 +0900 (538c4f6)
@@ -29,6 +29,31 @@ namespace grnxx {
 namespace map {
 
 template <typename T>
+class AllKeysCursor : public MapCursor<T> {
+ public:
+  using Key = typename Traits<T>::Type;
+  using KeyArg = typename Traits<T>::ArgumentType;
+
+  AllKeysCursor();
+  ~AllKeysCursor();
+
+  static AllKeysCursor *create(Map<T> *map, const MapCursorOptions &options);
+
+  bool next();
+  bool remove();
+
+ private:
+  Map<T> *map_;
+  int64_t cur_;
+  int64_t end_;
+  int64_t step_;
+  uint64_t count_;
+  MapCursorOptions options_;
+
+  bool init(Map<T> *map, const MapCursorOptions &options);
+};
+
+template <typename T>
 class KeyIDRangeCursor : public MapCursor<T> {
  public:
   using Key = typename Traits<T>::Type;

  Modified: lib/grnxx/map_cursor_query.hpp (+2 -2)
===================================================================
--- lib/grnxx/map_cursor_query.hpp    2013-05-27 15:58:28 +0900 (7e86ef8)
+++ lib/grnxx/map_cursor_query.hpp    2013-05-27 16:09:08 +0900 (b1ec769)
@@ -25,9 +25,9 @@
 
 namespace grnxx {
 
-// MapCursorAll.
+// MapCursorAllKeys.
 
-template <typename T> struct MapCursorAll {};
+template <typename T> struct MapCursorAllKeys {};
 
 // MapCursorKeyID
 
-------------- next part --------------
HTML����������������������������...
Download 



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