[Groonga-commit] groonga/grnxx at 74d70fc [master] Update grnxx::map::Patricia to support double.

アーカイブの一覧に戻る

susumu.yata null+****@clear*****
Fri Jun 21 11:05:27 JST 2013


susumu.yata	2013-06-21 11:05:27 +0900 (Fri, 21 Jun 2013)

  New Revision: 74d70fc8680425c48d6556021c6fa7c89b0db1ca
  https://github.com/groonga/grnxx/commit/74d70fc8680425c48d6556021c6fa7c89b0db1ca

  Message:
    Update grnxx::map::Patricia to support double.

  Modified files:
    lib/grnxx/map/patricia.cpp

  Modified: lib/grnxx/map/patricia.cpp (+24 -16)
===================================================================
--- lib/grnxx/map/patricia.cpp    2013-06-20 20:39:34 +0900 (5bc59d1)
+++ lib/grnxx/map/patricia.cpp    2013-06-21 11:05:27 +0900 (b4a3575)
@@ -174,6 +174,7 @@ bool Patricia<T>::unset(int64_t key_id) {
 
 template <typename T>
 bool Patricia<T>::find(KeyArg key, int64_t *key_id) {
+  const Key normalized_key = Helper<T>::normalize(key);
   uint64_t node_id = ROOT_NODE_ID;
   for ( ; ; ) {
     Node node;
@@ -192,7 +193,7 @@ bool Patricia<T>::find(KeyArg key, int64_t *key_id) {
           // Error.
           return false;
         }
-        if (!Helper<T>::equal_to(key, stored_key)) {
+        if (!Helper<T>::equal_to(normalized_key, stored_key)) {
           // Not found.
           return false;
         }
@@ -202,7 +203,7 @@ bool Patricia<T>::find(KeyArg key, int64_t *key_id) {
         return true;
       }
       case NODE_BRANCH: {
-        node_id = node.offset() + get_ith_bit(key, node.bit_pos());
+        node_id = node.offset() + get_ith_bit(normalized_key, node.bit_pos());
         break;
       }
     }
@@ -211,6 +212,7 @@ bool Patricia<T>::find(KeyArg key, int64_t *key_id) {
 
 template <typename T>
 bool Patricia<T>::add(KeyArg key, int64_t *key_id) {
+  const Key normalized_key = Helper<T>::normalize(key);
   uint64_t node_id = ROOT_NODE_ID;
   Node * node;
   for (node = nodes_->get_pointer(node_id);
@@ -220,7 +222,7 @@ bool Patricia<T>::add(KeyArg key, int64_t *key_id) {
       case NODE_DEAD: {
         // The patricia is empty.
         int64_t next_key_id;
-        if (!keys_->add(key, &next_key_id)) {
+        if (!keys_->add(normalized_key, &next_key_id)) {
           // Error.
           return false;
         }
@@ -231,7 +233,7 @@ bool Patricia<T>::add(KeyArg key, int64_t *key_id) {
         return true;
       }
       case NODE_BRANCH: {
-        node_id = node->offset() + get_ith_bit(key, node->bit_pos());
+        node_id = node->offset() + get_ith_bit(normalized_key, node->bit_pos());
         break;
       }
     }
@@ -246,7 +248,7 @@ bool Patricia<T>::add(KeyArg key, int64_t *key_id) {
     // Error.
     return false;
   }
-  const uint64_t count = count_common_prefix_bits(key, stored_key);
+  const uint64_t count = count_common_prefix_bits(normalized_key, stored_key);
   if (count == (sizeof(Key) * 8)) {
     // Found.
     if (key_id) {
@@ -263,12 +265,12 @@ bool Patricia<T>::add(KeyArg key, int64_t *key_id) {
       case NODE_BRANCH: {
         if (count <= node->bit_pos()) {
           int64_t next_key_id;
-          if (!keys_->add(key, &next_key_id)) {
+          if (!keys_->add(normalized_key, &next_key_id)) {
             // Error.
             return false;
           }
           // Create a branch node.
-          if (get_ith_bit(key, count)) {
+          if (get_ith_bit(normalized_key, count)) {
             next_nodes[0] = *node;
             next_nodes[1] = Node::leaf_node(next_key_id);
           } else {
@@ -284,7 +286,7 @@ bool Patricia<T>::add(KeyArg key, int64_t *key_id) {
         }
         node_id = node->offset();
         if (node->bit_pos() < count) {
-          node_id += get_ith_bit(key, node->bit_pos());
+          node_id += get_ith_bit(normalized_key, node->bit_pos());
         }
         break;
       }
@@ -295,12 +297,12 @@ bool Patricia<T>::add(KeyArg key, int64_t *key_id) {
     return false;
   }
   int64_t next_key_id;
-  if (!keys_->add(key, &next_key_id)) {
+  if (!keys_->add(normalized_key, &next_key_id)) {
     // Error.
     return false;
   }
   // Create a branch node.
-  if (get_ith_bit(key, count)) {
+  if (get_ith_bit(normalized_key, count)) {
     next_nodes[0] = *node;
     next_nodes[1] = Node::leaf_node(next_key_id);
   } else {
@@ -317,6 +319,7 @@ bool Patricia<T>::add(KeyArg key, int64_t *key_id) {
 
 template <typename T>
 bool Patricia<T>::remove(KeyArg key) {
+  const Key normalized_key = Helper<T>::normalize(key);
   uint64_t node_id = ROOT_NODE_ID;
   Node * prev_node = nullptr;
   for ( ; ; ) {
@@ -336,7 +339,7 @@ bool Patricia<T>::remove(KeyArg key) {
           // Error.
           return false;
         }
-        if (!Helper<T>::equal_to(key, stored_key)) {
+        if (!Helper<T>::equal_to(normalized_key, stored_key)) {
           // Not found.
           return false;
         }
@@ -350,7 +353,7 @@ bool Patricia<T>::remove(KeyArg key) {
         return true;
       }
       case NODE_BRANCH: {
-        node_id = node->offset() + get_ith_bit(key, node->bit_pos());
+        node_id = node->offset() + get_ith_bit(normalized_key, node->bit_pos());
         break;
       }
     }
@@ -436,8 +439,9 @@ uint64_t Patricia<T>::get_ith_bit(KeyArg key, uint64_t bit_pos) {
 
 template <>
 uint64_t Patricia<double>::get_ith_bit(KeyArg key, uint64_t bit_pos) {
-  // TODO
-  return 0;
+  int64_t x = *reinterpret_cast<const int64_t *>(&key);
+  x ^= (x >> 63) | (1ULL << 63);
+  return (x >> ((sizeof(Key) * 8) - 1 - bit_pos)) & 1;
 }
 
 template <>
@@ -456,8 +460,12 @@ uint64_t Patricia<T>::count_common_prefix_bits(KeyArg lhs, KeyArg rhs) {
 
 template <>
 uint64_t Patricia<double>::count_common_prefix_bits(KeyArg lhs, KeyArg rhs) {
-  // TODO
-  return 0;
+  const uint64_t x = *reinterpret_cast<const uint64_t *>(&lhs);
+  const uint64_t y = *reinterpret_cast<const uint64_t *>(&rhs);
+  if (x == y) {
+    return sizeof(Key) * 8;
+  }
+  return (sizeof(Key) * 8) - 1 - bit_scan_reverse(x ^ y);
 }
 
 template <>
-------------- next part --------------
HTML����������������������������...
ダウンロード 



More information about the Groonga-commit mailing list
アーカイブの一覧に戻る