susumu.yata
null+****@clear*****
Thu Apr 18 15:21:08 JST 2013
susumu.yata 2013-04-18 15:21:08 +0900 (Thu, 18 Apr 2013) New Revision: b1cea81513165ee60503a431c422e1b8738c08f0 https://github.com/groonga/grnxx/commit/b1cea81513165ee60503a431c422e1b8738c08f0 Message: Add IDCursor for DoubleArray<T>. Modified files: lib/grnxx/alpha/map/cursor.cpp lib/grnxx/alpha/map/double_array.cpp lib/grnxx/alpha/map/double_array.hpp Modified: lib/grnxx/alpha/map/cursor.cpp (+0 -1) =================================================================== --- lib/grnxx/alpha/map/cursor.cpp 2013-04-18 14:48:29 +0900 (ea185ed) +++ lib/grnxx/alpha/map/cursor.cpp 2013-04-18 15:21:08 +0900 (246c8d4) @@ -136,7 +136,6 @@ void IDCursor<T>::init_order_by_key(int64_t min, int64_t max) { template <> void IDCursor<GeoPoint>::init_order_by_key(int64_t, int64_t) { // Not supported. - return; } template class IDCursor<int8_t>; Modified: lib/grnxx/alpha/map/double_array.cpp (+148 -0) =================================================================== --- lib/grnxx/alpha/map/double_array.cpp 2013-04-18 14:48:29 +0900 (6dad5cb) +++ lib/grnxx/alpha/map/double_array.cpp 2013-04-18 15:21:08 +0900 (3b43699) @@ -17,7 +17,9 @@ */ #include "grnxx/alpha/map/double_array.hpp" +#include <algorithm> #include <cmath> +#include <vector> #include "../config.h" #include "grnxx/lock.hpp" @@ -482,6 +484,146 @@ class DoubleArrayEntryForOthers { }; template <typename T> +class DoubleArrayIDCursor : public MapCursor<T> { + public: + DoubleArrayIDCursor(DoubleArray<T> *double_array, + int64_t min, int64_t max, + const MapCursorOptions &options); + ~DoubleArrayIDCursor(); + + bool next(); + bool remove(); + + private: + DoubleArray<T> *double_array_; + int64_t cur_; + int64_t end_; + int64_t step_; + uint64_t count_; + MapCursorOptions options_; + std::vector<std::pair<T, int64_t>> keys_; + + void init_order_by_id(int64_t min, int64_t max); + void init_order_by_key(int64_t min, int64_t max); +}; + +template <typename T> +DoubleArrayIDCursor<T>::DoubleArrayIDCursor( + DoubleArray<T> *double_array, int64_t min, int64_t max, + const MapCursorOptions &options) + : MapCursor<T>(), double_array_(double_array), cur_(), end_(), step_(), + count_(0), options_(options), keys_() { + if (min < 0) { + min = 0; + } else if (options_.flags & MAP_CURSOR_EXCEPT_MIN) { + ++min; + } + + if ((max < 0) || (max > double_array_->max_key_id())) { + max = double_array_->max_key_id(); + } else if (options_.flags & MAP_CURSOR_EXCEPT_MAX) { + --max; + } + + if (min > max) { + cur_ = end_ = 0; + return; + } + + if ((options_.flags & MAP_CURSOR_ORDER_BY_ID) || + (~options_.flags & MAP_CURSOR_ORDER_BY_KEY)) { + init_order_by_id(min, max); + } else { + init_order_by_key(min, max); + } +} + +template <typename T> +DoubleArrayIDCursor<T>::~DoubleArrayIDCursor() {} + +template <typename T> +bool DoubleArrayIDCursor<T>::next() { + if (count_ >= options_.limit) { + return false; + } + if (options_.flags & MAP_CURSOR_ORDER_BY_ID) { + while (cur_ != end_) { + cur_ += step_; + if (double_array_->get(cur_, &this->key_)) { + this->key_id_ = cur_; + ++count_; + return true; + } + } + } else if (cur_ != end_) { + cur_ += step_; + this->key_ = keys_[cur_].first; + this->key_id_ = keys_[cur_].second; + ++count_; + return true; + } + return false; +} + +template <typename T> +bool DoubleArrayIDCursor<T>::remove() { + return double_array_->unset(this->key_id_); +} + +template <typename T> +void DoubleArrayIDCursor<T>::init_order_by_id(int64_t min, int64_t max) { + options_.flags |= MAP_CURSOR_ORDER_BY_ID; + options_.flags &= ~MAP_CURSOR_ORDER_BY_KEY; + + if (~options_.flags & MAP_CURSOR_REVERSE_ORDER) { + cur_ = min - 1; + end_ = max; + step_ = 1; + } else { + cur_ = max + 1; + end_ = min; + step_ = -1; + } + + uint64_t count = 0; + while ((count < options_.offset) && (cur_ != end_)) { + cur_ += step_; + if (double_array_->get(cur_)) { + ++count; + } + } +} + +template <typename T> +void DoubleArrayIDCursor<T>::init_order_by_key(int64_t min, int64_t max) { + cur_ = min - 1; + end_ = max; + while (cur_ != end_) { + ++cur_; + T key; + if (double_array_->get(cur_, &key)) { + keys_.push_back(std::make_pair(key, cur_)); + } + } + std::sort(keys_.begin(), keys_.end()); + + if (~options_.flags & MAP_CURSOR_REVERSE_ORDER) { + cur_ = -1; + end_ = keys_.size() - 1; + step_ = 1; + } else { + cur_ = keys_.size(); + end_ = 0; + step_ = -1; + } +} + +template <> +void DoubleArrayIDCursor<GeoPoint>::init_order_by_key(int64_t, int64_t) { + // Not supported. +} + +template <typename T> DoubleArray<T>::~DoubleArray() { if (!initialized_) try { // Free allocated blocks if initialization failed. @@ -751,6 +893,12 @@ void DoubleArray<T>::truncate() { } template <typename T> +MapCursor<T> *DoubleArray<T>::open_id_cursor(int64_t min, int64_t max, + const MapCursorOptions &options) { + return new (std::nothrow) DoubleArrayIDCursor<T>(this, min, max, options); +} + +template <typename T> DoubleArray<T>::DoubleArray() : pool_(), block_info_(nullptr), Modified: lib/grnxx/alpha/map/double_array.hpp (+2 -2) =================================================================== --- lib/grnxx/alpha/map/double_array.hpp 2013-04-18 14:48:29 +0900 (df12d3d) +++ lib/grnxx/alpha/map/double_array.hpp 2013-04-18 15:21:08 +0900 (7b6b51f) @@ -100,8 +100,8 @@ class DoubleArray : public Map<T> { // TODO // MapCursor<T> *open_basic_cursor( // const MapCursorOptions &options = MapCursorOptions()); -// MapCursor<T> *open_id_cursor(int64_t min, int64_t max, -// const MapCursorOptions &options = MapCursorOptions()); + MapCursor<T> *open_id_cursor(int64_t min, int64_t max, + const MapCursorOptions &options = MapCursorOptions()); // MapCursor<T> *open_key_cursor(T min, T max, // const MapCursorOptions &options = MapCursorOptions()); -------------- next part -------------- HTML����������������������������...Download