Skip to content

Commit f5aec7a

Browse files
committed
entry deltas
1 parent 93ebbd1 commit f5aec7a

File tree

3 files changed

+65
-0
lines changed

3 files changed

+65
-0
lines changed

include/sketch/sketch_columns.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ class FixedSizeSketchColumn {
5454
void reset_sample_state() {
5555
//no-op
5656
};
57+
58+
const ColumnEntryDelta generate_entry_delta(vec_t update) const;
59+
void apply_entry_delta(const ColumnEntryDelta &delta);
60+
5761

5862
inline bool is_initialized() const {
5963
return buckets != nullptr;
@@ -113,6 +117,10 @@ FRIEND_TEST(SketchColumnTestSuite, TestUpdateReallocation);
113117
SketchSample<vec_t> sample() const;
114118
void clear();
115119
void update(const vec_t update);
120+
121+
const ColumnEntryDelta generate_entry_delta(vec_t update) const;
122+
void apply_entry_delta(const ColumnEntryDelta &delta);
123+
116124
void atomic_update(const vec_t update);
117125
void merge(ResizeableSketchColumn const& other);
118126
uint8_t get_depth() const;
@@ -184,6 +192,10 @@ class ResizeableAlignedSketchColumn {
184192
SketchSample<vec_t> sample() const;
185193
void clear();
186194
void update(const vec_t update);
195+
196+
const ColumnEntryDelta generate_entry_delta(vec_t update) const;
197+
void apply_entry_delta(const ColumnEntryDelta &delta);
198+
187199
void atomic_update(const vec_t update) {
188200
// TODO - implement later
189201
this->update(update);

include/sketch/sketch_concept.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ struct SketchSample {
1515
SampleResult result;
1616
};
1717

18+
// TODO - figure out how to template this instead of using vec_t
19+
struct ColumnEntryDelta {
20+
Bucket bucket;
21+
uint16_t depth;
22+
};
1823

1924

2025
template <typename T = vec_t> requires(std::integral<T>)
@@ -38,6 +43,8 @@ concept ConnectivitySketchConcept = requires(T t, T other) {
3843
template <typename T, typename V>
3944
concept SketchColumnConcept = requires(T t, T other) {
4045
{ t.sample() } -> std::same_as<SketchSample<V>>;
46+
{ t.generate_entry_delta(std::declval<V>()) } -> std::same_as<const ColumnEntryDelta>;
47+
{ t.apply_entry_delta(std::declval<const ColumnEntryDelta>()) } -> std::same_as<void>;
4148
{ t.update(std::declval<V>()) } -> std::same_as<void>;
4249
// require an atomic_update function.
4350
// up to implementer whether it uses locks or simply atomic XOR

src/sketch_columns.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,18 @@ void FixedSizeSketchColumn::update(const vec_t update) {
111111
deterministic_bucket ^= {update, checksum};
112112
}
113113

114+
const ColumnEntryDelta FixedSizeSketchColumn::generate_entry_delta(vec_t update) const {
115+
vec_hash_t checksum = Bucket_Boruvka::get_index_hash(update, seed);
116+
col_hash_t depth = Bucket_Boruvka::get_index_depth_legacy(update, seed, capacity-1);
117+
return {Bucket{update, checksum}, static_cast<uint16_t>(depth)};
118+
}
119+
120+
void FixedSizeSketchColumn::apply_entry_delta(const ColumnEntryDelta &delta) {
121+
assert(delta.depth < capacity);
122+
buckets[delta.depth] ^= delta.bucket;
123+
deterministic_bucket ^= delta.bucket;
124+
}
125+
114126
void FixedSizeSketchColumn::atomic_update(const vec_t update) {
115127
vec_hash_t checksum = Bucket_Boruvka::get_index_hash(update, seed);
116128
col_hash_t depth = Bucket_Boruvka::get_index_depth_legacy(update, seed, capacity-1);
@@ -247,6 +259,23 @@ void ResizeableSketchColumn::update(const vec_t update) {
247259
buckets[depth] ^= {update, checksum};
248260
}
249261

262+
const ColumnEntryDelta ResizeableSketchColumn::generate_entry_delta(vec_t update) const {
263+
vec_hash_t checksum = Bucket_Boruvka::get_index_hash(update, seed);
264+
col_hash_t depth = Bucket_Boruvka::get_index_depth_legacy(update, seed, 60);
265+
return {Bucket{update, checksum}, static_cast<uint16_t>(depth)};
266+
}
267+
268+
void ResizeableSketchColumn::apply_entry_delta(const ColumnEntryDelta &delta) {
269+
assert(delta.depth < capacity);
270+
deterministic_bucket ^= delta.bucket;
271+
272+
if (delta.depth >= capacity) {
273+
size_t new_capacity = ((delta.depth >> 2) << 2) + 4;
274+
reallocate(new_capacity);
275+
}
276+
buckets[delta.depth] ^= delta.bucket;
277+
}
278+
250279
void ResizeableSketchColumn::atomic_update(const vec_t update) {
251280
vec_hash_t checksum = Bucket_Boruvka::get_index_hash(update, seed);
252281
col_hash_t depth = Bucket_Boruvka::get_index_depth_legacy(update, seed, 60);
@@ -378,6 +407,23 @@ void ResizeableAlignedSketchColumn::update(const vec_t update) {
378407
aligned_buckets[depth] ^= {update, checksum};
379408
}
380409

410+
const ColumnEntryDelta ResizeableAlignedSketchColumn::generate_entry_delta(vec_t update) const {
411+
vec_hash_t checksum = Bucket_Boruvka::get_index_hash(update, seed);
412+
col_hash_t depth = Bucket_Boruvka::get_index_depth_legacy(update, seed, 60);
413+
return {Bucket{update, checksum}, static_cast<uint16_t>(depth)};
414+
}
415+
416+
void ResizeableAlignedSketchColumn::apply_entry_delta(const ColumnEntryDelta &delta) {
417+
assert(delta.depth < capacity);
418+
deterministic_bucket ^= delta.bucket;
419+
420+
if (delta.depth >= capacity) {
421+
size_t new_capacity = ((delta.depth >> 2) << 2) + 4;
422+
reallocate(new_capacity);
423+
}
424+
aligned_buckets[delta.depth] ^= delta.bucket;
425+
}
426+
381427
void ResizeableAlignedSketchColumn::merge(ResizeableAlignedSketchColumn const& other) {
382428
deterministic_bucket ^= other.deterministic_bucket;
383429
if (other.capacity > capacity) {

0 commit comments

Comments
 (0)