susumu.yata
null+****@clear*****
Mon Mar 11 16:45:30 JST 2013
susumu.yata 2013-03-11 16:45:30 +0900 (Mon, 11 Mar 2013) New Revision: ee52a0b7c550ee00d6ce605fb7884a794841796d https://github.com/groonga/grnxx/commit/ee52a0b7c550ee00d6ce605fb7884a794841796d Message: Add scan() to grnxx::Map. Modified files: lib/map.cpp lib/map.hpp test/test_map.cpp Modified: lib/map.cpp (+43 -39) =================================================================== --- lib/map.cpp 2013-03-11 16:07:40 +0900 (3bc989a) +++ lib/map.cpp 2013-03-11 16:45:30 +0900 (729450c) @@ -27,6 +27,47 @@ MapOptions::MapOptions() : type(MAP_UNKNOWN) {} MapHeader::MapHeader() : type(MAP_UNKNOWN) {} +MapScan::~MapScan() {} + +MapScan *MapScan::open(Map *map, const Slice &query, GetChar get_char) { + std::unique_ptr<MapScan> scan(new (std::nothrow) MapScan); + if (!scan) { + GRNXX_ERROR() << "new grnxx::MapScan failed"; + GRNXX_THROW(); + } + scan->map_ = map; + scan->query_ = query; + scan->get_char_ = get_char; + return scan.release(); +} + +bool MapScan::next() { + offset_ += size_; + while (offset_ < query_.size()) { + const Slice query_left = query_.subslice(offset_, query_.size() - offset_); + if (map_->lcp_search(query_left, &key_id_, &key_)) { + size_ = key_.size(); + return true; + } + // Move to the next character. + if (get_char_) { + offset_ += get_char_(query_left).size(); + } else { + ++offset_; + } + } + size_ = 0; + return false; +} + +MapScan::MapScan() + : map_(nullptr), + query_(), + offset_(0), + size_(0), + key_id_(-1), + key_() {} + Map::Map() {} Map::~Map() {} @@ -102,45 +143,8 @@ void Map::unlink(io::Pool pool, uint32_t block_id) { // TODO: Unknown type error! } -MapScan::~MapScan() {} - -MapScan *MapScan::open(Map *map, const Slice &query, GetChar get_char) { - std::unique_ptr<MapScan> scan(new (std::nothrow) MapScan); - if (!scan) { - GRNXX_ERROR() << "new grnxx::MapScan failed"; - GRNXX_THROW(); - } - scan->map_ = map; - scan->query_ = query; - scan->get_char_ = get_char; - return scan.release(); -} - -bool MapScan::next() { - offset_ += size_; - while (offset_ < query_.size()) { - const Slice query_left = query_.subslice(offset_, query_.size() - offset_); - if (map_->lcp_search(query_left, &key_id_, &key_)) { - size_ = key_.size(); - return true; - } - // Move to the next character. - if (get_char_) { - offset_ += get_char_(query_left).size(); - } else { - ++offset_; - } - } - size_ = 0; - return false; +MapScan *Map::scan(const Slice &query, MapScan::GetChar get_char) { + return MapScan::open(this, query, get_char); } -MapScan::MapScan() - : map_(nullptr), - query_(), - offset_(0), - size_(0), - key_id_(-1), - key_() {} - } // namespace grnxx Modified: lib/map.hpp (+53 -47) =================================================================== --- lib/map.hpp 2013-03-11 16:07:40 +0900 (a01dcf2) +++ lib/map.hpp 2013-03-11 16:45:30 +0900 (c45bc10) @@ -122,6 +122,55 @@ inline std::ostream &operator<<(std::ostream &stream, const MapKey &key) { return stream << key.slice(); } +class Map; + +class MapScan { + public: + typedef Slice (*GetChar)(const Slice &); + + ~MapScan(); + + // Create an object to find keys in "query". + static MapScan *open(Map *map, const Slice &query, + GetChar get_char = nullptr); + + // Scan the rest of the query and return true iff a key is found (success). + // On success, the found key is accessible via accessors. + bool next(); + + // Return the query. + const Slice &query() const { + return query_; + } + // Return the start position of the found key. + uint64_t offset() const { + return offset_; + } + // Return the size of the found key. + uint64_t size() const { + return size_; + } + // Return the ID of the found key. + int64_t key_id() const { + return key_id_; + } + // Return a reference to the found key. + const MapKey &key() const { + return key_; + } + + protected: + Map *map_; + Slice query_; + uint64_t offset_; + uint64_t size_; + int64_t key_id_; + MapKey key_; + GetChar get_char_; + + MapScan(); +}; + class Map { public: Map(); @@ -168,54 +217,11 @@ class Map { virtual bool update(const Slice &src_key, const Slice &dest_key, int64_t *key_id = nullptr) = 0; - // TODO -}; - -class MapScan { - public: - typedef Slice (*GetChar)(const Slice &); - - ~MapScan(); - - // Create an object to find keys in "query". - static MapScan *open(Map *map, const Slice &query, - GetChar get_char = nullptr); - - // Scan the rest of the query and return true iff a key is found (success). - // On success, the found key is accessible via accessors. - bool next(); - - // Return the query. - const Slice &query() const { - return query_; - } - // Return the start position of the found key. - uint64_t offset() const { - return offset_; - } - // Return the size of the found key. - uint64_t size() const { - return size_; - } - // Return the ID of the found key. - int64_t key_id() const { - return key_id_; - } - // Return a reference to the found key. - const MapKey &key() const { - return key_; - } - - protected: - Map *map_; - Slice query_; - uint64_t offset_; - uint64_t size_; - int64_t key_id_; - MapKey key_; - GetChar get_char_; + // Start scan to find keys in "query" and return an object for the scan. + // The object must be deleted after the scan. + MapScan *scan(const Slice &query, MapScan::GetChar get_char = nullptr); - MapScan(); + // TODO }; } // namespace grnxx Modified: test/test_map.cpp (+3 -23) =================================================================== --- test/test_map.cpp 2013-03-11 16:07:40 +0900 (6571221) +++ test/test_map.cpp 2013-03-11 16:45:30 +0900 (bbe5f74) @@ -149,7 +149,7 @@ void test_scan() { grnxx::Slice query = "ABCDXEFG"; - std::unique_ptr<grnxx::MapScan> scan(grnxx::MapScan::open(map.get(), query)); + std::unique_ptr<grnxx::MapScan> scan(map->scan(query)); assert(scan->next()); assert(scan->offset() == 0); @@ -167,30 +167,10 @@ void test_scan() { grnxx::MapScan::GetChar get_char = [](const grnxx::Slice &slice) -> grnxx::Slice { - return slice ? slice.prefix(1) : grnxx::Slice(); + return slice ? slice.prefix(2) : grnxx::Slice(); }; - scan.reset(grnxx::MapScan::open(map.get(), query, get_char)); - - assert(scan->next()); - assert(scan->offset() == 0); - assert(scan->size() == 4); - assert(scan->key_id() == 1); - assert(scan->key() == "ABCD"); - - assert(scan->next()); - assert(scan->offset() == 5); - assert(scan->size() == 3); - assert(scan->key_id() == 5); - assert(scan->key() == "EFG"); - - assert(!scan->next()); - - get_char = [](const grnxx::Slice &slice) -> grnxx::Slice { - return slice ? slice.prefix(2) : grnxx::Slice(); - }; - - scan.reset(grnxx::MapScan::open(map.get(), query, get_char)); + scan.reset(map->scan(query, get_char)); assert(scan->next()); assert(scan->offset() == 0); -------------- next part -------------- HTML����������������������������...Download