[Groonga-commit] groonga/grnxx [master] Update grnxx::alpha::map::Array for NaN.

Back to archive index

susumu.yata null+****@clear*****
Fri Apr 5 15:14:56 JST 2013


susumu.yata	2013-04-05 15:14:56 +0900 (Fri, 05 Apr 2013)

  New Revision: 45737732a9ce0dceb91a449ce771f3332aba3c79
  https://github.com/groonga/grnxx/commit/45737732a9ce0dceb91a449ce771f3332aba3c79

  Message:
    Update grnxx::alpha::map::Array for NaN.

  Modified files:
    lib/grnxx/alpha/map/array.cpp
    test/test_alpha_map.cpp

  Modified: lib/grnxx/alpha/map/array.cpp (+30 -5)
===================================================================
--- lib/grnxx/alpha/map/array.cpp    2013-04-05 10:48:31 +0900 (f6b37fd)
+++ lib/grnxx/alpha/map/array.cpp    2013-04-05 15:14:56 +0900 (c93bdd7)
@@ -17,9 +17,34 @@
 */
 #include "array.hpp"
 
+#include <cmath>
+
 namespace grnxx {
 namespace alpha {
 namespace map {
+namespace {
+
+template <typename T>
+bool equal_to(T x, T y) {
+  return x == y;
+}
+
+template <>
+bool equal_to(double x, double y) {
+  return (std::isnan(x) && std::isnan(y)) || (x == y);
+}
+
+template <typename T>
+T normalize(T x) {
+  return x;
+}
+
+template <>
+double normalize(double x) {
+  return std::isnan(x) ? std::numeric_limits<double>::quiet_NaN() : x;
+}
+
+}  // namespace
 
 ArrayHeader::ArrayHeader()
   : map_type(MAP_ARRAY),
@@ -113,7 +138,7 @@ bool Array<T>::reset(int64_t key_id, T dest_key) {
   if (search(dest_key)) {
     return false;
   }
-  keys_[key_id] = dest_key;
+  keys_[key_id] = normalize(dest_key);
   return true;
 }
 
@@ -121,7 +146,7 @@ template <typename T>
 bool Array<T>::search(T key, int64_t *key_id) {
   for (int64_t i = 0; i <= header_->max_key_id; ++i) {
     if (get_bit(i)) {
-      if (key == keys_[i]) {
+      if (equal_to(key, keys_[i])) {
         if (key_id) {
           *key_id = i;
         }
@@ -137,7 +162,7 @@ bool Array<T>::insert(T key, int64_t *key_id) {
   int64_t key_id_candidate = -1;
   for (int64_t i = 0; i <= header_->max_key_id; ++i) {
     if (get_bit(i)) {
-      if (key == keys_[i]) {
+      if (equal_to(key, keys_[i])) {
         if (key_id) {
           *key_id = i;
         }
@@ -151,7 +176,7 @@ bool Array<T>::insert(T key, int64_t *key_id) {
   if (key_id_candidate == -1) {
     key_id_candidate = ++header_->max_key_id;
   }
-  keys_[key_id_candidate] = key;
+  keys_[key_id_candidate] = normalize(key);
   set_bit(key_id_candidate, true);
   if (key_id) {
     *key_id = key_id_candidate;
@@ -178,7 +203,7 @@ bool Array<T>::update(T src_key, T dest_key, int64_t *key_id) {
   if (search(dest_key)) {
     return false;
   }
-  keys_[src_key_id] = dest_key;
+  keys_[src_key_id] = normalize(dest_key);
   if (key_id) {
     *key_id = src_key_id;
   }

  Modified: test/test_alpha_map.cpp (+41 -0)
===================================================================
--- test/test_alpha_map.cpp    2013-04-05 10:48:31 +0900 (4b179f7)
+++ test/test_alpha_map.cpp    2013-04-05 15:14:56 +0900 (d96dc9d)
@@ -16,6 +16,7 @@
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
 #include <cassert>
+#include <cmath>
 #include <random>
 #include <unordered_map>
 
@@ -142,6 +143,44 @@ void test_map() {
   }
 }
 
+void test_nan() {
+  grnxx::io::Pool pool;
+  pool.open(grnxx::io::POOL_ANONYMOUS);
+
+  std::unique_ptr<grnxx::alpha::Map<double>> map;
+  map.reset(map->create(grnxx::alpha::MAP_ARRAY, pool));
+
+  const double nan = std::numeric_limits<double>::quiet_NaN();
+
+  std::int64_t key_id;
+  assert(map->insert(nan, &key_id));
+  assert(key_id == 0);
+  assert(!map->insert(nan));
+
+  double key;
+  assert(map->get(key_id, &key));
+  assert(std::isnan(key));
+  assert(map->search(nan, &key_id));
+  assert(key_id == 0);
+
+  assert(map->unset(key_id));
+  assert(!map->unset(key_id));
+
+  assert(map->insert(nan));
+  assert(map->remove(nan));
+  assert(!map->remove(nan));
+
+  assert(!map->reset(nan, nan));
+  assert(map->insert(nan, &key_id));
+  assert(!map->reset(key_id, nan));
+  assert(map->reset(key_id, 0.0));
+  assert(map->reset(key_id, nan));
+
+  assert(!map->update(nan, nan));
+  assert(map->update(nan, 0.0));
+  assert(map->update(0.0, nan));
+}
+
 int main() {
   grnxx::Logger::set_flags(grnxx::LOGGER_WITH_ALL |
                            grnxx::LOGGER_ENABLE_COUT);
@@ -157,5 +196,7 @@ int main() {
   test_map<uint64_t>();
   test_map<double>();
 
+  test_nan();
+
   return 0;
 }
-------------- next part --------------
HTML����������������������������...
Download 



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