susumu.yata
null+****@clear*****
Tue Mar 5 15:22:01 JST 2013
susumu.yata 2013-03-05 15:22:01 +0900 (Tue, 05 Mar 2013) New Revision: 8122828363548d78749cd85b5c03ddfec27530ca https://github.com/groonga/grnxx/commit/8122828363548d78749cd85b5c03ddfec27530ca Log: Add grnxx::MapScan TODO: Solve encoding problems. Modified files: lib/map.cpp lib/map.hpp test/test_map.cpp Modified: lib/map.cpp (+39 -0) =================================================================== --- lib/map.cpp 2013-03-01 23:59:41 +0900 (8ccc714) +++ lib/map.cpp 2013-03-05 15:22:01 +0900 (f02ebde) @@ -18,6 +18,9 @@ #include "map.hpp" #include "map/double_array.hpp" +#include "exception.hpp" +#include "logger.hpp" + namespace grnxx { MapOptions::MapOptions() : type(MAP_UNKNOWN) {} @@ -99,4 +102,40 @@ void Map::unlink(io::Pool pool, uint32_t block_id) { // TODO: Unknown type error! } +MapScan::~MapScan() {} + +MapScan *MapScan::open(Map *map, const Slice &query) { + 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; + return scan.release(); +} + +bool MapScan::next() { + offset_ += size_; + while (offset_ < query_.size()) { + if (map_->lcp_search(query_.subslice(offset_, query_.size() - offset_), + &key_id_, &key_)) { + size_ = key_.size(); + return true; + } + // TODO: Move to the next character, not the next byte. + ++offset_; + } + size_ = 0; + return false; +} + +MapScan::MapScan() + : map_(nullptr), + query_(), + offset_(0), + size_(0), + key_id_(-1), + key_() {} + } // namespace grnxx Modified: lib/map.hpp (+43 -0) =================================================================== --- lib/map.hpp 2013-03-01 23:59:41 +0900 (48e57e5) +++ lib/map.hpp 2013-03-05 15:22:01 +0900 (49ed9cb) @@ -173,6 +173,49 @@ class Map { // TODO }; +class MapScan { + public: + ~MapScan(); + + // Create an object to find keys in "query". + static MapScan *open(Map *map, const Slice &query); + + // 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_; + + MapScan(); +}; + } // namespace grnxx #endif // GRNXX_MAP_HPP Modified: test/test_map.cpp (+36 -0) =================================================================== --- test/test_map.cpp 2013-03-01 23:59:41 +0900 (d358b62) +++ test/test_map.cpp 2013-03-05 15:22:01 +0900 (e690ece) @@ -130,6 +130,41 @@ void test_lcp_search() { assert(!map->lcp_search("BCD", &key_id, &key)); } +void test_scan() { + grnxx::io::Pool pool; + pool.open(grnxx::io::POOL_TEMPORARY); + + grnxx::MapOptions options; + options.type = grnxx::MAP_DOUBLE_ARRAY; + std::unique_ptr<grnxx::Map> map(grnxx::Map::create(options, pool)); + + assert(map->insert("AB")); + assert(map->insert("ABCD")); + assert(map->insert("BCD")); + assert(map->insert("CDE")); + assert(map->insert("EF")); + assert(map->insert("EFG")); + assert(map->insert("EFGH")); + + grnxx::Slice query = "ABCDXEFG"; + + std::unique_ptr<grnxx::MapScan> scan(grnxx::MapScan::open(map.get(), query)); + + 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()); +} + void create_keys(std::size_t num_keys, std::size_t min_size, std::size_t max_size, std::unordered_set<std::string> *both_keys, @@ -308,6 +343,7 @@ int main() { test_basics(); test_lcp_search(); + test_scan(); test_insert(); test_remove(); -------------- next part -------------- HTML����������������������������...Download