Skip to content

Commit 46c945d

Browse files
committed
refactor: remove update sketch
1 parent 9381dcd commit 46c945d

4 files changed

Lines changed: 79 additions & 141 deletions

File tree

tuple/include/array_of_strings_sketch.hpp

Lines changed: 24 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,12 @@ struct default_array_of_strings_serde {
6969
static void check_utf8(const std::string& value);
7070
};
7171

72+
/**
73+
* Hashes an array of strings using ArrayOfStrings-compatible hashing.
74+
*/
75+
template<typename Allocator = std::allocator<std::string>>
76+
uint64_t hash_array_of_strings_key(const array<std::string, Allocator>& key);
77+
7278
/**
7379
* Extended class of compact_tuple_sketch for array of strings
7480
* Requirements: all strings must be valid UTF-8 and array size must be <= 127.
@@ -125,63 +131,26 @@ class compact_array_of_strings_tuple_sketch:
125131
};
126132

127133
/**
128-
* Extended class of update_tuple_sketch for array of strings
134+
* Convenience alias for update_tuple_sketch for array of strings
129135
*/
130-
template<template<typename> class Policy = default_array_of_strings_update_policy,
131-
typename Allocator = std::allocator<std::string>>
132-
class update_array_of_strings_tuple_sketch:
133-
public update_tuple_sketch<
134-
array<std::string, Allocator>,
135-
array<std::string, Allocator>,
136-
Policy<Allocator>,
137-
typename std::allocator_traits<Allocator>::template rebind_alloc<array<std::string, Allocator>>
138-
> {
139-
public:
140-
using array_of_strings = array<std::string, Allocator>;
141-
using summary_allocator = typename std::allocator_traits<Allocator>::template rebind_alloc<array_of_strings>;
142-
using policy_type = Policy<Allocator>;
143-
using Base = update_tuple_sketch<
144-
array_of_strings,
145-
array_of_strings,
146-
policy_type,
147-
summary_allocator
148-
>;
149-
using resize_factor = typename Base::resize_factor;
150-
class builder;
151-
using Base::update;
152-
153-
/**
154-
* Updates the sketch with string array for both key and value.
155-
* @param key the given string array key
156-
* @param value the given string array value
157-
*/
158-
void update(const array_of_strings& key, const array_of_strings& value);
136+
template<typename Allocator = std::allocator<std::string>,
137+
typename Policy = default_array_of_strings_update_policy<Allocator>>
138+
using update_array_of_strings_tuple_sketch = update_tuple_sketch<
139+
array<std::string, Allocator>,
140+
array<std::string, Allocator>,
141+
Policy,
142+
typename std::allocator_traits<Allocator>::template rebind_alloc<array<std::string, Allocator>>
143+
>;
159144

160-
/**
161-
* Converts this sketch to a compact sketch (ordered or unordered).
162-
* @param ordered optional flag to specify if an ordered sketch should be produced
163-
* @return compact array of strings sketch
164-
*/
165-
compact_array_of_strings_tuple_sketch<Allocator> compact(bool ordered = true) const;
166-
167-
private:
168-
update_array_of_strings_tuple_sketch(uint8_t lg_cur_size, uint8_t lg_nom_size, resize_factor rf, float p, uint64_t theta,
169-
uint64_t seed, const policy_type& policy, const summary_allocator& allocator);
170-
171-
// Matches Java Util.PRIME for ArrayOfStrings key hashing.
172-
static constexpr uint64_t STRING_ARR_HASH_SEED = 0x7A3CCA71ULL;
173-
174-
static uint64_t hash_key(const array_of_strings& key);
175-
};
176-
177-
template<template<typename> class Policy, typename Allocator>
178-
class update_array_of_strings_tuple_sketch<Policy, Allocator>::builder:
179-
public tuple_base_builder<builder, policy_type, summary_allocator> {
180-
public:
181-
builder(const policy_type& policy = policy_type(), const summary_allocator& allocator = summary_allocator());
182-
183-
update_array_of_strings_tuple_sketch build() const;
184-
};
145+
/**
146+
* Converts an array of strings tuple sketch to a compact sketch (ordered or unordered).
147+
* @param sketch input sketch
148+
* @param ordered optional flag to specify if an ordered sketch should be produced
149+
* @return compact array of strings sketch
150+
*/
151+
template<typename Allocator = std::allocator<std::string>, typename Policy = default_array_of_strings_update_policy<Allocator>>
152+
compact_array_of_strings_tuple_sketch<Allocator> compact_array_of_strings_sketch(
153+
const update_array_of_strings_tuple_sketch<Allocator, Policy>& sketch, bool ordered = true);
185154

186155
} /* namespace datasketches */
187156

tuple/include/array_of_strings_sketch_impl.hpp

Lines changed: 11 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -58,23 +58,10 @@ void default_array_of_strings_update_policy<Allocator>::update(
5858
for (size_t i = 0; i < length; ++i) array[i] = (*input)[i];
5959
}
6060

61-
template<template<typename> class Policy, typename Allocator>
62-
update_array_of_strings_tuple_sketch<Policy, Allocator>::update_array_of_strings_tuple_sketch(
63-
uint8_t lg_cur_size, uint8_t lg_nom_size, resize_factor rf, float p, uint64_t theta,
64-
uint64_t seed, const policy_type& policy, const summary_allocator& allocator
65-
):
66-
Base(lg_cur_size, lg_nom_size, rf, p, theta, seed, policy, allocator) {}
67-
68-
template<template<typename> class Policy, typename Allocator>
69-
void update_array_of_strings_tuple_sketch<Policy, Allocator>::update(
70-
const array_of_strings& key, const array_of_strings& value
71-
) {
72-
const uint64_t hash = hash_key(key);
73-
Base::update(hash, value);
74-
}
75-
76-
template<template<typename> class Policy, typename Allocator>
77-
uint64_t update_array_of_strings_tuple_sketch<Policy, Allocator>::hash_key(const array_of_strings& key) {
61+
template<typename Allocator>
62+
uint64_t hash_array_of_strings_key(const array<std::string, Allocator>& key) {
63+
// Matches Java Util.PRIME for ArrayOfStrings key hashing.
64+
static constexpr uint64_t STRING_ARR_HASH_SEED = 0x7A3CCA71ULL;
7865
XXHash64 hasher(STRING_ARR_HASH_SEED);
7966
const auto size = static_cast<size_t>(key.size());
8067
for (size_t i = 0; i < size; ++i) {
@@ -85,31 +72,11 @@ uint64_t update_array_of_strings_tuple_sketch<Policy, Allocator>::hash_key(const
8572
return hasher.hash();
8673
}
8774

88-
template<template<typename> class Policy, typename Allocator>
89-
compact_array_of_strings_tuple_sketch<Allocator> update_array_of_strings_tuple_sketch<Policy, Allocator>::compact(bool ordered) const {
90-
return compact_array_of_strings_tuple_sketch<Allocator>(*this, ordered);
91-
}
92-
93-
// builder
94-
95-
template<template<typename> class Policy, typename Allocator>
96-
update_array_of_strings_tuple_sketch<Policy, Allocator>::builder::builder(
97-
const policy_type& policy, const summary_allocator& allocator
98-
):
99-
tuple_base_builder<builder, policy_type, summary_allocator>(policy, allocator) {}
100-
101-
template<template<typename> class Policy, typename Allocator>
102-
auto update_array_of_strings_tuple_sketch<Policy, Allocator>::builder::build() const -> update_array_of_strings_tuple_sketch {
103-
return update_array_of_strings_tuple_sketch(
104-
this->starting_lg_size(),
105-
this->lg_k_,
106-
this->rf_,
107-
this->p_,
108-
this->starting_theta(),
109-
this->seed_,
110-
this->policy_,
111-
this->allocator_
112-
);
75+
template<typename Allocator, typename Policy>
76+
compact_array_of_strings_tuple_sketch<Allocator> compact_array_of_strings_sketch(
77+
const update_array_of_strings_tuple_sketch<Allocator, Policy>& sketch, bool ordered
78+
) {
79+
return compact_array_of_strings_tuple_sketch<Allocator>(sketch, ordered);
11380
}
11481

11582
template<typename Allocator>
@@ -183,7 +150,7 @@ void default_array_of_strings_serde<Allocator>::deserialize(
183150
if (!is) throw std::runtime_error("array_of_strings stream read failed");
184151
std::string value(length, '\0');
185152
if (length != 0) {
186-
is.read(value.data(), length);
153+
is.read(&value[0], length);
187154
if (!is) throw std::runtime_error("array_of_strings stream read failed");
188155
}
189156
check_utf8(value);
@@ -241,7 +208,7 @@ size_t default_array_of_strings_serde<Allocator>::deserialize(
241208
bytes_read += copy_from_mem(ptr8 + bytes_read, length);
242209
std::string value(length, '\0');
243210
if (length != 0) {
244-
bytes_read += copy_from_mem(ptr8 + bytes_read, value.data(), length);
211+
bytes_read += copy_from_mem(ptr8 + bytes_read, &value[0], length);
245212
}
246213
check_utf8(value);
247214
array[j] = std::move(value);

tuple/test/aos_sketch_serialize_for_java.cpp

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
namespace datasketches {
2727

2828
using aos_sketch = update_array_of_strings_tuple_sketch<>;
29-
using array_of_strings = aos_sketch::array_of_strings;
29+
using array_of_strings = array<std::string>;
3030

3131
static array_of_strings make_array(std::initializer_list<std::string> items) {
3232
array_of_strings array(static_cast<uint8_t>(items.size()), "");
@@ -47,12 +47,12 @@ TEST_CASE("aos sketch generate one value", "[serialize_for_java]") {
4747
key[0] = std::to_string(i);
4848
array_of_strings value(1, "");
4949
value[0] = "value" + std::to_string(i);
50-
sketch.update(key, value);
50+
sketch.update(hash_array_of_strings_key(key), value);
5151
}
5252
REQUIRE(sketch.is_empty() == (n == 0));
5353
REQUIRE(sketch.get_estimate() == Approx(n).margin(n * 0.03));
5454
std::ofstream os("aos_1_n" + std::to_string(n) + "_cpp.sk", std::ios::binary);
55-
sketch.compact().serialize(os, default_array_of_strings_serde<>());
55+
compact_array_of_strings_sketch(sketch).serialize(os, default_array_of_strings_serde<>());
5656
}
5757
}
5858

@@ -67,12 +67,12 @@ TEST_CASE("aos sketch generate three values", "[serialize_for_java]") {
6767
value[0] = "a" + std::to_string(i);
6868
value[1] = "b" + std::to_string(i);
6969
value[2] = "c" + std::to_string(i);
70-
sketch.update(key, value);
70+
sketch.update(hash_array_of_strings_key(key), value);
7171
}
7272
REQUIRE(sketch.is_empty() == (n == 0));
7373
REQUIRE(sketch.get_estimate() == Approx(n).margin(n * 0.03));
7474
std::ofstream os("aos_3_n" + std::to_string(n) + "_cpp.sk", std::ios::binary);
75-
sketch.compact().serialize(os, default_array_of_strings_serde<>());
75+
compact_array_of_strings_sketch(sketch).serialize(os, default_array_of_strings_serde<>());
7676
}
7777
}
7878

@@ -86,11 +86,11 @@ TEST_CASE("aos sketch generate non-empty no entries", "[serialize_for_java]") {
8686
key[0] = "key1";
8787
array_of_strings value(1, "");
8888
value[0] = "value1";
89-
sketch.update(key, value);
89+
sketch.update(hash_array_of_strings_key(key), value);
9090
REQUIRE_FALSE(sketch.is_empty());
9191
REQUIRE(sketch.get_num_retained() == 0);
9292
std::ofstream os("aos_1_non_empty_no_entries_cpp.sk", std::ios::binary);
93-
sketch.compact().serialize(os, default_array_of_strings_serde<>());
93+
compact_array_of_strings_sketch(sketch).serialize(os, default_array_of_strings_serde<>());
9494
}
9595

9696
TEST_CASE("aos sketch generate multi key strings", "[serialize_for_java]") {
@@ -103,53 +103,44 @@ TEST_CASE("aos sketch generate multi key strings", "[serialize_for_java]") {
103103
key[1] = "subkey" + std::to_string(i % 10);
104104
array_of_strings value(1, "");
105105
value[0] = "value" + std::to_string(i);
106-
sketch.update(key, value);
106+
sketch.update(hash_array_of_strings_key(key), value);
107107
}
108108
REQUIRE(sketch.is_empty() == (n == 0));
109109
REQUIRE(sketch.get_estimate() == Approx(n).margin(n * 0.03));
110110
std::ofstream os("aos_multikey_n" + std::to_string(n) + "_cpp.sk", std::ios::binary);
111-
sketch.compact().serialize(os, default_array_of_strings_serde<>());
111+
compact_array_of_strings_sketch(sketch).serialize(os, default_array_of_strings_serde<>());
112112
}
113113
}
114114

115115
TEST_CASE("aos sketch generate unicode strings", "[serialize_for_java]") {
116116
auto sketch = aos_sketch::builder().build();
117117
sketch.update(
118-
make_array({u8"", u8"열쇠"}),
118+
hash_array_of_strings_key(make_array({u8"", u8"열쇠"})),
119119
make_array({u8"밸류", u8""})
120120
);
121121
sketch.update(
122-
make_array({u8"🔑", u8"🗝️"}),
122+
hash_array_of_strings_key(make_array({u8"🔑", u8"🗝️"})),
123123
make_array({u8"📦", u8"🎁"})
124124
);
125125
sketch.update(
126-
make_array({u8"ключ1", u8"ключ2"}),
126+
hash_array_of_strings_key(make_array({u8"ключ1", u8"ключ2"})),
127127
make_array({u8"ценить1", u8"ценить2"})
128128
);
129129
REQUIRE_FALSE(sketch.is_empty());
130130
REQUIRE(sketch.get_num_retained() == 3);
131131
std::ofstream os("aos_unicode_cpp.sk", std::ios::binary);
132-
sketch.compact().serialize(os, default_array_of_strings_serde<>());
132+
compact_array_of_strings_sketch(sketch).serialize(os, default_array_of_strings_serde<>());
133133
}
134134

135135
TEST_CASE("aos sketch generate empty strings", "[serialize_for_java]") {
136136
auto sketch = aos_sketch::builder().build();
137-
sketch.update(
138-
make_array({""}),
139-
make_array({"empty_key_value"})
140-
);
141-
sketch.update(
142-
make_array({"empty_value_key"}),
143-
make_array({""})
144-
);
145-
sketch.update(
146-
make_array({"", ""}),
147-
make_array({"", ""})
148-
);
137+
sketch.update(hash_array_of_strings_key(make_array({""})), make_array({"empty_key_value"}));
138+
sketch.update(hash_array_of_strings_key(make_array({"empty_value_key"})), make_array({""}));
139+
sketch.update(hash_array_of_strings_key(make_array({"", ""})), make_array({"", ""}));
149140
REQUIRE_FALSE(sketch.is_empty());
150141
REQUIRE(sketch.get_num_retained() == 3);
151142
std::ofstream os("aos_empty_strings_cpp.sk", std::ios::binary);
152-
sketch.compact().serialize(os, default_array_of_strings_serde<>());
143+
compact_array_of_strings_sketch(sketch).serialize(os, default_array_of_strings_serde<>());
153144
}
154145

155146
} /* namespace datasketches */

0 commit comments

Comments
 (0)