diff --git a/sampling/include/var_opt_sketch.hpp b/sampling/include/var_opt_sketch.hpp index 6b157caa..df080c6e 100644 --- a/sampling/include/var_opt_sketch.hpp +++ b/sampling/include/var_opt_sketch.hpp @@ -272,7 +272,7 @@ class var_opt_sketch { typedef typename std::allocator_traits::template rebind_alloc AllocDouble; typedef typename std::allocator_traits::template rebind_alloc AllocBool; - static const uint32_t MIN_LG_ARR_ITEMS = 3; + static const uint32_t MIN_LG_ARR_ITEMS = 4; static const uint8_t PREAMBLE_LONGS_EMPTY = 1; static const uint8_t PREAMBLE_LONGS_WARMUP = 3; diff --git a/sampling/include/var_opt_sketch_impl.hpp b/sampling/include/var_opt_sketch_impl.hpp index 36ee3fc8..30d526af 100644 --- a/sampling/include/var_opt_sketch_impl.hpp +++ b/sampling/include/var_opt_sketch_impl.hpp @@ -772,12 +772,11 @@ string var_opt_sketch::items_to_string(bool print_gap) const { template template void var_opt_sketch::update(O&& item, double weight, bool mark) { - if (weight < 0.0 || std::isnan(weight) || std::isinf(weight)) { - throw std::invalid_argument("Item weights must be nonnegative and finite. Found: " + if (weight <= 0.0 || std::isnan(weight) || std::isinf(weight)) { + throw std::invalid_argument("Item weights must be positive and finite. Found: " + std::to_string(weight)); - } else if (weight == 0.0) { - return; } + ++n_; if (r_ == 0) { diff --git a/sampling/test/var_opt_sketch_test.cpp b/sampling/test/var_opt_sketch_test.cpp index 71d16e91..179d7016 100644 --- a/sampling/test/var_opt_sketch_test.cpp +++ b/sampling/test/var_opt_sketch_test.cpp @@ -178,11 +178,17 @@ TEST_CASE("varopt sketch: non-empty degenerate sketch", "[var_opt_sketch]") { TEST_CASE("varopt sketch: invalid weight", "[var_opt_sketch]") { var_opt_sketch sk(100, resize_factor::X2); - REQUIRE_THROWS_AS(sk.update("invalid_weight", -1.0), std::invalid_argument); - // should not throw but sketch should still be empty - sk.update("zero weight", 0.0); - REQUIRE(sk.is_empty()); + // Negative + REQUIRE_THROWS_AS(sk.update("invalid_weight", -1.0), std::invalid_argument); + // Zero + REQUIRE_THROWS_AS(sk.update("zero_weight", 0.0), std::invalid_argument); + // NaN + REQUIRE_THROWS_AS(sk.update("NaN_weight", std::numeric_limits::quiet_NaN()), std::invalid_argument); + // +Inf + REQUIRE_THROWS_AS(sk.update("positive_infinity", std::numeric_limits::infinity()), std::invalid_argument); + // -Inf + REQUIRE_THROWS_AS(sk.update("negative_infinity", -std::numeric_limits::infinity()), std::invalid_argument); } TEST_CASE("varopt sketch: corrupt serialized weight", "[var_opt_sketch]") {