[Groonga-commit] groonga/grnxx [master] Add grnxx::MapScan

Back to archive index

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 



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