You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@datasketches.apache.org by al...@apache.org on 2020/08/06 03:49:27 UTC
[incubator-datasketches-cpp] branch tuple_sketch updated: set
number of values at runtime
This is an automated email from the ASF dual-hosted git repository.
alsay pushed a commit to branch tuple_sketch
in repository https://gitbox.apache.org/repos/asf/incubator-datasketches-cpp.git
The following commit(s) were added to refs/heads/tuple_sketch by this push:
new 6712a3e set number of values at runtime
6712a3e is described below
commit 6712a3e7ef5ce45f5abc3afe8718cf2f207d1ef1
Author: AlexanderSaydakov <Al...@users.noreply.github.com>
AuthorDate: Wed Aug 5 20:49:15 2020 -0700
set number of values at runtime
---
tuple/include/array_of_doubles_sketch.hpp | 67 +++++++++++----
tuple/include/array_of_doubles_sketch_impl.hpp | 110 ++++++++++++++++---------
tuple/include/tuple_sketch.hpp | 4 +-
tuple/test/aod_2_compact_exact_from_java.sk | Bin 0 -> 24024 bytes
tuple/test/aod_3_compact_empty_from_java.sk | 1 +
tuple/test/array_of_doubles_sketch_test.cpp | 86 +++++++++++++++----
6 files changed, 200 insertions(+), 68 deletions(-)
diff --git a/tuple/include/array_of_doubles_sketch.hpp b/tuple/include/array_of_doubles_sketch.hpp
index b869470..cb1977e 100644
--- a/tuple/include/array_of_doubles_sketch.hpp
+++ b/tuple/include/array_of_doubles_sketch.hpp
@@ -29,24 +29,58 @@ namespace datasketches {
// equivalent of ArrayOfDoublesSketch in Java
-template<int num>
-struct array_of_doubles_update_policy {
- std::array<double, num> create() const {
- return std::array<double, num>();
+template<typename A = std::allocator<std::vector<double>>>
+class array_of_doubles_update_policy {
+public:
+ array_of_doubles_update_policy(uint8_t num_values = 1, const A& allocator = A()):
+ allocator(allocator), num_values(num_values) {}
+ std::vector<double> create() const {
+ return std::vector<double>(num_values, 0, allocator);
+ }
+ void update(std::vector<double>& summary, const std::vector<double>& update) const {
+ for (uint8_t i = 0; i < num_values; ++i) summary[i] += update[i];
}
- void update(std::array<double, num>& summary, const std::array<double, num>& update) const {
- for (int i = 0; i < num; ++i) summary[i] += update[i];
+ uint8_t get_num_values() const {
+ return num_values;
}
+
+private:
+ A allocator;
+ uint8_t num_values;
};
-template<int num, typename A = std::allocator<std::array<double, num>>>
-using update_array_of_doubles_sketch = update_tuple_sketch<
- std::array<double, num>, std::array<double, num>, array_of_doubles_update_policy<num>, A>;
+// forward declaration
+template<typename A> class compact_array_of_doubles_sketch;
-template<int num, typename A = std::allocator<std::array<double, num>>>
-class compact_array_of_doubles_sketch: public compact_tuple_sketch<std::array<double, num>, A> {
+template<typename A = std::allocator<std::vector<double>>>
+class update_array_of_doubles_sketch: public update_tuple_sketch<std::vector<double>, std::vector<double>,
+array_of_doubles_update_policy<A>, A> {
public:
- using Summary = std::array<double, num>;
+ using Base = update_tuple_sketch<std::vector<double>, std::vector<double>, array_of_doubles_update_policy<A>, A>;
+ using resize_factor = typename Base::resize_factor;
+
+ class builder;
+
+ compact_array_of_doubles_sketch<A> compact(bool ordered = true) const;
+ uint8_t get_num_values() const;
+
+private:
+ // for builder
+ update_array_of_doubles_sketch(uint8_t lg_cur_size, uint8_t lg_nom_size, resize_factor rf, uint64_t theta,
+ uint64_t seed, const array_of_doubles_update_policy<A>& policy, const A& allocator);
+};
+
+template<typename A>
+class update_array_of_doubles_sketch<A>::builder: public Base::builder {
+public:
+ builder(const array_of_doubles_update_policy<A>& policy = array_of_doubles_update_policy<A>(), const A& allocator = A());
+ update_array_of_doubles_sketch<A> build() const;
+};
+
+template<typename A = std::allocator<std::vector<double>>>
+class compact_array_of_doubles_sketch: public compact_tuple_sketch<std::vector<double>, A> {
+public:
+ using Summary = std::vector<double>;
using Base = compact_tuple_sketch<Summary, A>;
using Entry = typename Base::Entry;
using AllocEntry = typename Base::AllocEntry;
@@ -57,14 +91,19 @@ public:
static const uint8_t SKETCH_TYPE = 3;
enum flags { UNUSED1, UNUSED2, IS_EMPTY, HAS_ENTRIES, IS_ORDERED };
- compact_array_of_doubles_sketch(const Base& other, bool ordered = true);
+ template<typename Sketch>
+ compact_array_of_doubles_sketch(const Sketch& other, bool ordered = true);
+
+ uint8_t get_num_values() const;
void serialize(std::ostream& os) const;
static compact_array_of_doubles_sketch deserialize(std::istream& is, uint64_t seed = DEFAULT_SEED, const A& allocator = A());
// for internal use
- compact_array_of_doubles_sketch(bool is_empty, bool is_ordered, uint16_t seed_hash, uint64_t theta, std::vector<Entry, AllocEntry>&& entries);
+ compact_array_of_doubles_sketch(bool is_empty, bool is_ordered, uint16_t seed_hash, uint64_t theta, std::vector<Entry, AllocEntry>&& entries, uint8_t num_values);
+private:
+ uint8_t num_values;
};
} /* namespace datasketches */
diff --git a/tuple/include/array_of_doubles_sketch_impl.hpp b/tuple/include/array_of_doubles_sketch_impl.hpp
index db0cac3..77e3b2b 100644
--- a/tuple/include/array_of_doubles_sketch_impl.hpp
+++ b/tuple/include/array_of_doubles_sketch_impl.hpp
@@ -19,93 +19,127 @@
namespace datasketches {
-template<int num, typename A>
-compact_array_of_doubles_sketch<num, A>::compact_array_of_doubles_sketch(const Base& other, bool ordered):
-Base(other, ordered) {}
+template<typename A>
+update_array_of_doubles_sketch<A>::update_array_of_doubles_sketch(uint8_t lg_cur_size, uint8_t lg_nom_size, resize_factor rf,
+ uint64_t theta, uint64_t seed, const array_of_doubles_update_policy<A>& policy, const A& allocator):
+Base(lg_cur_size, lg_nom_size, rf, theta, seed, policy, allocator) {}
-template<int num, typename A>
-compact_array_of_doubles_sketch<num, A>::compact_array_of_doubles_sketch(bool is_empty, bool is_ordered, uint16_t seed_hash, uint64_t theta, std::vector<Entry, AllocEntry>&& entries):
-Base(is_empty, is_ordered, seed_hash, theta, std::move(entries)) {}
-template<int num, typename A>
-void compact_array_of_doubles_sketch<num, A>::serialize(std::ostream& os) const {
+template<typename A>
+uint8_t update_array_of_doubles_sketch<A>::get_num_values() const {
+ return this->policy_.get_num_values();
+}
+
+template<typename A>
+compact_array_of_doubles_sketch<A> update_array_of_doubles_sketch<A>::compact(bool ordered) const {
+ return compact_array_of_doubles_sketch<A>(*this, ordered);
+}
+
+// builder
+
+template<typename A>
+update_array_of_doubles_sketch<A>::builder::builder(const array_of_doubles_update_policy<A>& policy, const A& allocator):
+Base::builder(policy, allocator) {}
+
+template<typename A>
+update_array_of_doubles_sketch<A> update_array_of_doubles_sketch<A>::builder::build() const {
+ return update_array_of_doubles_sketch<A>(this->starting_lg_size(), this->lg_k_, this->rf_, this->starting_theta(), this->seed_, this->policy_, this->allocator_);
+}
+
+// compact sketch
+
+template<typename A>
+template<typename S>
+compact_array_of_doubles_sketch<A>::compact_array_of_doubles_sketch(const S& other, bool ordered):
+Base(other, ordered), num_values(other.get_num_values()) {}
+
+template<typename A>
+compact_array_of_doubles_sketch<A>::compact_array_of_doubles_sketch(bool is_empty, bool is_ordered,
+ uint16_t seed_hash, uint64_t theta, std::vector<Entry, AllocEntry>&& entries, uint8_t num_values):
+Base(is_empty, is_ordered, seed_hash, theta, std::move(entries)), num_values(num_values) {}
+
+template<typename A>
+uint8_t compact_array_of_doubles_sketch<A>::get_num_values() const {
+ return num_values;
+}
+
+template<typename A>
+void compact_array_of_doubles_sketch<A>::serialize(std::ostream& os) const {
const uint8_t preamble_longs = 1;
- os.write((char*)&preamble_longs, sizeof(preamble_longs));
+ os.write(reinterpret_cast<const char*>(&preamble_longs), sizeof(preamble_longs));
const uint8_t serial_version = SERIAL_VERSION;
- os.write((char*)&serial_version, sizeof(serial_version));
+ os.write(reinterpret_cast<const char*>(&serial_version), sizeof(serial_version));
const uint8_t family = SKETCH_FAMILY;
- os.write((char*)&family, sizeof(family));
+ os.write(reinterpret_cast<const char*>(&family), sizeof(family));
const uint8_t type = SKETCH_TYPE;
- os.write((char*)&type, sizeof(type));
+ os.write(reinterpret_cast<const char*>(&type), sizeof(type));
const uint8_t flags_byte(
(this->is_empty() ? 1 << flags::IS_EMPTY : 0) |
(this->get_num_retained() > 0 ? 1 << flags::HAS_ENTRIES : 0) |
(this->is_ordered() ? 1 << flags::IS_ORDERED : 0)
);
- os.write((char*)&flags_byte, sizeof(flags_byte));
- const uint8_t num_values = num;
+ os.write(reinterpret_cast<const char*>(&flags_byte), sizeof(flags_byte));
os.write(reinterpret_cast<const char*>(&num_values), sizeof(num_values));
const uint16_t seed_hash = this->get_seed_hash();
- os.write((char*)&seed_hash, sizeof(seed_hash));
- os.write((char*)&(this->theta_), sizeof(uint64_t));
+ os.write(reinterpret_cast<const char*>(&seed_hash), sizeof(seed_hash));
+ os.write(reinterpret_cast<const char*>(&(this->theta_)), sizeof(uint64_t));
if (this->get_num_retained() > 0) {
const uint32_t num_entries = this->entries_.size();
- os.write((char*)&num_entries, sizeof(num_entries));
+ os.write(reinterpret_cast<const char*>(&num_entries), sizeof(num_entries));
const uint32_t unused32 = 0;
- os.write((char*)&unused32, sizeof(unused32));
+ os.write(reinterpret_cast<const char*>(&unused32), sizeof(unused32));
for (const auto& it: this->entries_) {
- os.write((char*)&it.first, sizeof(uint64_t));
+ os.write(reinterpret_cast<const char*>(&it.first), sizeof(uint64_t));
}
for (const auto& it: this->entries_) {
- os.write((char*)&it.second, sizeof(Summary));
+ os.write(reinterpret_cast<const char*>(it.second.data()), it.second.size() * sizeof(double));
}
}
}
-template<int num, typename A>
-compact_array_of_doubles_sketch<num, A> compact_array_of_doubles_sketch<num, A>::deserialize(std::istream& is, uint64_t seed, const A& allocator) {
+template<typename A>
+compact_array_of_doubles_sketch<A> compact_array_of_doubles_sketch<A>::deserialize(std::istream& is, uint64_t seed, const A& allocator) {
uint8_t preamble_longs;
- is.read((char*)&preamble_longs, sizeof(preamble_longs));
+ is.read(reinterpret_cast<char*>(&preamble_longs), sizeof(preamble_longs));
uint8_t serial_version;
- is.read((char*)&serial_version, sizeof(serial_version));
+ is.read(reinterpret_cast<char*>(&serial_version), sizeof(serial_version));
uint8_t family;
- is.read((char*)&family, sizeof(family));
+ is.read(reinterpret_cast<char*>(&family), sizeof(family));
uint8_t type;
- is.read((char*)&type, sizeof(type));
+ is.read(reinterpret_cast<char*>(&type), sizeof(type));
uint8_t flags_byte;
- is.read((char*)&flags_byte, sizeof(flags_byte));
+ is.read(reinterpret_cast<char*>(&flags_byte), sizeof(flags_byte));
uint8_t num_values;
- is.read((char*)&num_values, sizeof(num_values));
+ is.read(reinterpret_cast<char*>(&num_values), sizeof(num_values));
uint16_t seed_hash;
- is.read((char*)&seed_hash, sizeof(seed_hash));
+ is.read(reinterpret_cast<char*>(&seed_hash), sizeof(seed_hash));
checker<true>::check_sketch_family(family, SKETCH_FAMILY);
checker<true>::check_sketch_type(type, SKETCH_TYPE);
checker<true>::check_serial_version(serial_version, SERIAL_VERSION);
- check_value(num_values, static_cast<uint8_t>(num), "number of values");
const bool has_entries = flags_byte & (1 << flags::HAS_ENTRIES);
if (has_entries) checker<true>::check_seed_hash(seed_hash, compute_seed_hash(seed));
uint64_t theta;
- is.read((char*)&theta, sizeof(theta));
+ is.read(reinterpret_cast<char*>(&theta), sizeof(theta));
std::vector<Entry, AllocEntry> entries(allocator);
uint32_t num_entries = 0;
if (has_entries) {
- is.read((char*)&num_entries, sizeof(num_entries));
+ is.read(reinterpret_cast<char*>(&num_entries), sizeof(num_entries));
uint32_t unused32;
- is.read((char*)&unused32, sizeof(unused32));
+ is.read(reinterpret_cast<char*>(&unused32), sizeof(unused32));
entries.reserve(num_entries);
std::vector<uint64_t, AllocU64> keys(num_entries, 0, allocator);
- is.read((char*)keys.data(), num_entries * sizeof(uint64_t));
- std::vector<Summary, A> summaries(num_entries, Summary(), allocator);
- is.read((char*)summaries.data(), num_entries * sizeof(Summary));
+ is.read(reinterpret_cast<char*>(keys.data()), num_entries * sizeof(uint64_t));
for (size_t i = 0; i < num_entries; ++i) {
- entries.push_back(Entry(keys[i], summaries[i]));
+ Summary s(num_values, 0, allocator);
+ is.read(reinterpret_cast<char*>(s.data()), num_values * sizeof(double));
+ entries.push_back(Entry(keys[i], std::move(s)));
}
}
if (!is.good()) throw std::runtime_error("error reading from std::istream");
const bool is_empty = flags_byte & (1 << flags::IS_EMPTY);
const bool is_ordered = flags_byte & (1 << flags::IS_ORDERED);
- return compact_array_of_doubles_sketch(is_empty, is_ordered, seed_hash, theta, std::move(entries));
+ return compact_array_of_doubles_sketch(is_empty, is_ordered, seed_hash, theta, std::move(entries), num_values);
}
} /* namespace datasketches */
diff --git a/tuple/include/tuple_sketch.hpp b/tuple/include/tuple_sketch.hpp
index 915f170..7e2475a 100644
--- a/tuple/include/tuple_sketch.hpp
+++ b/tuple/include/tuple_sketch.hpp
@@ -325,7 +325,7 @@ public:
virtual const_iterator begin() const;
virtual const_iterator end() const;
-private:
+protected:
Policy policy_;
tuple_map map_;
@@ -475,7 +475,7 @@ public:
*/
update_tuple_sketch<S, U, P, A> build() const;
-private:
+protected:
P policy_;
A allocator_;
};
diff --git a/tuple/test/aod_2_compact_exact_from_java.sk b/tuple/test/aod_2_compact_exact_from_java.sk
new file mode 100644
index 0000000..a14fd08
Binary files /dev/null and b/tuple/test/aod_2_compact_exact_from_java.sk differ
diff --git a/tuple/test/aod_3_compact_empty_from_java.sk b/tuple/test/aod_3_compact_empty_from_java.sk
new file mode 100644
index 0000000..1579d9b
--- /dev/null
+++ b/tuple/test/aod_3_compact_empty_from_java.sk
@@ -0,0 +1 @@
+ ̓�������
\ No newline at end of file
diff --git a/tuple/test/array_of_doubles_sketch_test.cpp b/tuple/test/array_of_doubles_sketch_test.cpp
index f72861b..539962a 100644
--- a/tuple/test/array_of_doubles_sketch_test.cpp
+++ b/tuple/test/array_of_doubles_sketch_test.cpp
@@ -34,7 +34,7 @@ const std::string inputPath = "test/";
#endif
TEST_CASE("aod sketch: serialization compatibility with java - empty", "[tuple_sketch]") {
- auto update_sketch = update_array_of_doubles_sketch<1>::builder().build();
+ auto update_sketch = update_array_of_doubles_sketch<>::builder().build();
REQUIRE(update_sketch.is_empty());
REQUIRE(update_sketch.get_num_retained() == 0);
auto compact_sketch = update_sketch.compact();
@@ -43,7 +43,27 @@ TEST_CASE("aod sketch: serialization compatibility with java - empty", "[tuple_s
std::ifstream is;
is.exceptions(std::ios::failbit | std::ios::badbit);
is.open(inputPath + "aod_1_compact_empty_from_java.sk", std::ios::binary);
- auto compact_sketch_from_java = compact_array_of_doubles_sketch<1>::deserialize(is);
+ auto compact_sketch_from_java = compact_array_of_doubles_sketch<>::deserialize(is);
+ REQUIRE(compact_sketch.get_num_retained() == compact_sketch_from_java.get_num_retained());
+ REQUIRE(compact_sketch.get_theta() == Approx(compact_sketch_from_java.get_theta()).margin(1e-10));
+ REQUIRE(compact_sketch.get_estimate() == Approx(compact_sketch_from_java.get_estimate()).margin(1e-10));
+ REQUIRE(compact_sketch.get_lower_bound(1) == Approx(compact_sketch_from_java.get_lower_bound(1)).margin(1e-10));
+ REQUIRE(compact_sketch.get_upper_bound(1) == Approx(compact_sketch_from_java.get_upper_bound(1)).margin(1e-10));
+}
+
+TEST_CASE("aod sketch: serialization compatibility with java - empty configured for three values", "[tuple_sketch]") {
+ auto update_sketch = update_array_of_doubles_sketch<>::builder(3).build();
+ REQUIRE(update_sketch.is_empty());
+ REQUIRE(update_sketch.get_num_retained() == 0);
+ REQUIRE(update_sketch.get_num_values() == 3);
+ auto compact_sketch = update_sketch.compact();
+
+ // read binary sketch from Java
+ std::ifstream is;
+ is.exceptions(std::ios::failbit | std::ios::badbit);
+ is.open(inputPath + "aod_3_compact_empty_from_java.sk", std::ios::binary);
+ auto compact_sketch_from_java = compact_array_of_doubles_sketch<>::deserialize(is);
+ REQUIRE(compact_sketch.get_num_values() == compact_sketch_from_java.get_num_values());
REQUIRE(compact_sketch.get_num_retained() == compact_sketch_from_java.get_num_retained());
REQUIRE(compact_sketch.get_theta() == Approx(compact_sketch_from_java.get_theta()).margin(1e-10));
REQUIRE(compact_sketch.get_estimate() == Approx(compact_sketch_from_java.get_estimate()).margin(1e-10));
@@ -52,8 +72,8 @@ TEST_CASE("aod sketch: serialization compatibility with java - empty", "[tuple_s
}
TEST_CASE("aod sketch: serialization compatibility with java - non-empty no entries", "[tuple_sketch]") {
- auto update_sketch = update_array_of_doubles_sketch<1>::builder().set_p(0.01).build();
- std::array<double, 1> a = {1};
+ auto update_sketch = update_array_of_doubles_sketch<>::builder().set_p(0.01).build();
+ std::vector<double> a = {1};
update_sketch.update(1, a);
REQUIRE_FALSE(update_sketch.is_empty());
REQUIRE(update_sketch.get_num_retained() == 0);
@@ -63,7 +83,7 @@ TEST_CASE("aod sketch: serialization compatibility with java - non-empty no entr
std::ifstream is;
is.exceptions(std::ios::failbit | std::ios::badbit);
is.open(inputPath + "aod_1_compact_non_empty_no_entries_from_java.sk", std::ios::binary);
- auto compact_sketch_from_java = compact_array_of_doubles_sketch<1>::deserialize(is);
+ auto compact_sketch_from_java = compact_array_of_doubles_sketch<>::deserialize(is);
REQUIRE(compact_sketch.get_num_retained() == compact_sketch_from_java.get_num_retained());
REQUIRE(compact_sketch.get_theta() == Approx(compact_sketch_from_java.get_theta()).margin(1e-10));
REQUIRE(compact_sketch.get_estimate() == Approx(compact_sketch_from_java.get_estimate()).margin(1e-10));
@@ -72,8 +92,8 @@ TEST_CASE("aod sketch: serialization compatibility with java - non-empty no entr
}
TEST_CASE("aod sketch: serialization compatibility with java - estimation mode", "[tuple_sketch]") {
- auto update_sketch = update_array_of_doubles_sketch<1>::builder().build();
- std::array<double, 1> a = {1};
+ auto update_sketch = update_array_of_doubles_sketch<>::builder().build();
+ std::vector<double> a = {1};
for (int i = 0; i < 8192; ++i) update_sketch.update(i, a);
auto compact_sketch = update_sketch.compact();
@@ -81,7 +101,7 @@ TEST_CASE("aod sketch: serialization compatibility with java - estimation mode",
std::ifstream is;
is.exceptions(std::ios::failbit | std::ios::badbit);
is.open(inputPath + "aod_1_compact_estimation_from_java.sk", std::ios::binary);
- auto compact_sketch_from_java = compact_array_of_doubles_sketch<1>::deserialize(is);
+ auto compact_sketch_from_java = compact_array_of_doubles_sketch<>::deserialize(is);
REQUIRE(compact_sketch.get_num_retained() == compact_sketch_from_java.get_num_retained());
REQUIRE(compact_sketch.get_theta() == Approx(compact_sketch_from_java.get_theta()).margin(1e-10));
REQUIRE(compact_sketch.get_estimate() == Approx(compact_sketch_from_java.get_estimate()).margin(1e-10));
@@ -94,7 +114,7 @@ TEST_CASE("aod sketch: serialization compatibility with java - estimation mode",
// sketch from Java is not ordered
// transform it to ordered so that iteration sequence would match exactly
- compact_array_of_doubles_sketch<1> ordered_sketch_from_java(compact_sketch_from_java, true);
+ compact_array_of_doubles_sketch<> ordered_sketch_from_java(compact_sketch_from_java, true);
auto it = ordered_sketch_from_java.begin();
for (const auto& entry: compact_sketch) {
REQUIRE(entry == *it);
@@ -102,16 +122,51 @@ TEST_CASE("aod sketch: serialization compatibility with java - estimation mode",
}
}
+TEST_CASE("aod sketch: serialization compatibility with java - exact mode with two values", "[tuple_sketch]") {
+ auto update_sketch = update_array_of_doubles_sketch<>::builder(2).build();
+ std::vector<double> a = {1, 2};
+ for (int i = 0; i < 1000; ++i) update_sketch.update(i, a);
+ auto compact_sketch = update_sketch.compact();
+ REQUIRE_FALSE(compact_sketch.is_estimation_mode());
+
+ // read binary sketch from Java
+ std::ifstream is;
+ is.exceptions(std::ios::failbit | std::ios::badbit);
+ is.open(inputPath + "aod_2_compact_exact_from_java.sk", std::ios::binary);
+ auto compact_sketch_from_java = compact_array_of_doubles_sketch<>::deserialize(is);
+ REQUIRE(compact_sketch.get_num_retained() == compact_sketch_from_java.get_num_retained());
+ REQUIRE(compact_sketch.get_theta() == Approx(compact_sketch_from_java.get_theta()).margin(1e-10));
+ REQUIRE(compact_sketch.get_estimate() == Approx(compact_sketch_from_java.get_estimate()).margin(1e-10));
+ REQUIRE(compact_sketch.get_lower_bound(1) == Approx(compact_sketch_from_java.get_lower_bound(1)).margin(1e-10));
+ REQUIRE(compact_sketch.get_upper_bound(1) == Approx(compact_sketch_from_java.get_upper_bound(1)).margin(1e-10));
+ REQUIRE(compact_sketch.get_lower_bound(2) == Approx(compact_sketch_from_java.get_lower_bound(2)).margin(1e-10));
+ REQUIRE(compact_sketch.get_upper_bound(2) == Approx(compact_sketch_from_java.get_upper_bound(2)).margin(1e-10));
+ REQUIRE(compact_sketch.get_lower_bound(3) == Approx(compact_sketch_from_java.get_lower_bound(3)).margin(1e-10));
+ REQUIRE(compact_sketch.get_upper_bound(3) == Approx(compact_sketch_from_java.get_upper_bound(3)).margin(1e-10));
+
+ // sketch from Java is not ordered
+ // transform it to ordered so that iteration sequence would match exactly
+ compact_array_of_doubles_sketch<> ordered_sketch_from_java(compact_sketch_from_java, true);
+ auto it = ordered_sketch_from_java.begin();
+ for (const auto& entry: compact_sketch) {
+ REQUIRE(entry.first == (*it).first);
+ REQUIRE(entry.second.size() == 2);
+ REQUIRE(entry.second[0] == (*it).second[0]);
+ REQUIRE(entry.second[1] == (*it).second[1]);
+ ++it;
+ }
+}
+
TEST_CASE("aod sketch: serialize deserialize - estimation mode", "[tuple_sketch]") {
- auto update_sketch = update_array_of_doubles_sketch<2>::builder().build();
- std::array<double, 2> a = {1, 2};
+ auto update_sketch = update_array_of_doubles_sketch<>::builder(2).build();
+ std::vector<double> a = {1, 2};
for (int i = 0; i < 8192; ++i) update_sketch.update(i, a);
- compact_array_of_doubles_sketch<2> compact_sketch = update_sketch.compact();
+ auto compact_sketch = update_sketch.compact();
std::stringstream ss;
ss.exceptions(std::ios::failbit | std::ios::badbit);
compact_sketch.serialize(ss);
- auto deserialized_sketch = compact_array_of_doubles_sketch<2>::deserialize(ss);
+ auto deserialized_sketch = compact_array_of_doubles_sketch<>::deserialize(ss);
REQUIRE(compact_sketch.get_num_retained() == deserialized_sketch.get_num_retained());
REQUIRE(compact_sketch.get_theta() == Approx(deserialized_sketch.get_theta()).margin(1e-10));
REQUIRE(compact_sketch.get_estimate() == Approx(deserialized_sketch.get_estimate()).margin(1e-10));
@@ -124,7 +179,10 @@ TEST_CASE("aod sketch: serialize deserialize - estimation mode", "[tuple_sketch]
// sketches must be ordered and the iteration sequence must match exactly
auto it = deserialized_sketch.begin();
for (const auto& entry: compact_sketch) {
- REQUIRE(entry == *it);
+ REQUIRE(entry.first == (*it).first);
+ REQUIRE(entry.second.size() == 2);
+ REQUIRE(entry.second[0] == (*it).second[0]);
+ REQUIRE(entry.second[1] == (*it).second[1]);
++it;
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datasketches.apache.org
For additional commands, e-mail: commits-help@datasketches.apache.org