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