Skip to content

Commit b5f9220

Browse files
committed
Bring back sparse store
1 parent eecb9cc commit b5f9220

3 files changed

Lines changed: 520 additions & 0 deletions

File tree

ddsketch/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ install(FILES
5959
include/logarithmic_mapping_impl.hpp
6060
include/quadratically_interpolated_mapping.hpp
6161
include/quadratically_interpolated_mapping_impl.hpp
62+
include/sparse_store.hpp
63+
include/sparse_store_impl.hpp
6264
include/store_factory.hpp
6365
include/unbounded_size_dense_store.hpp
6466
include/unbounded_size_dense_store_impl.hpp

ddsketch/include/sparse_store.hpp

Lines changed: 275 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,275 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
#ifndef SPARSE_STORE_HPP
21+
#define SPARSE_STORE_HPP
22+
23+
#include <map>
24+
25+
#include "bin.hpp"
26+
27+
/**
28+
* @class SparseStore
29+
* @brief Sparse integer-indexed bins container backed by a std::map.
30+
*
31+
* @tparam Allocator Allocator type for internal storage.
32+
*/
33+
namespace datasketches {
34+
// Forward declaration
35+
template<class Derived, typename Allocator> class DenseStore;
36+
37+
template<typename Allocator>
38+
class SparseStore {
39+
public:
40+
41+
/**
42+
* @brief Bin storage type (contiguous counts).
43+
*/
44+
using bins_type = std::map<
45+
int,
46+
double,
47+
std::less<int>,
48+
typename std::allocator_traits<Allocator>::template rebind_alloc<std::pair<const int, double>>
49+
>;
50+
51+
// Forward declarations
52+
/**
53+
* @brief Forward iterator over non-empty bins (ascending index)
54+
*/
55+
class iterator;
56+
57+
/**
58+
* @brief Reverse iterator over non-empty bins (descending index)
59+
*/
60+
class reverse_iterator;
61+
62+
63+
/**
64+
* Default constructor
65+
*/
66+
SparseStore() = default;
67+
68+
bool operator==(const SparseStore &other) const;
69+
70+
/**
71+
* @brief Increment bin @p index by 1.
72+
*/
73+
void add(int index);
74+
75+
/**
76+
* @brief Increment bin @p index by @p count.
77+
*/
78+
void add(int index, double count);
79+
80+
/**
81+
* @brief Increment index by count as specified by @p bin.
82+
*/
83+
void add(const Bin& bin);
84+
85+
/**
86+
* @brief Create a heap-allocated copy of this store.
87+
* @return Pointer to a new CollapsingHighestDenseStore with identical contents.
88+
*/
89+
SparseStore<Allocator>* copy() const;
90+
91+
/**
92+
* @brief Clear all contents of the store.
93+
*/
94+
void clear();
95+
96+
/**
97+
* @brief Lowest non-empty bin inde.
98+
*/
99+
int get_min_index() const;
100+
101+
/**
102+
* @brief Highest non-empty bin index.
103+
*/
104+
int get_max_index() const;
105+
106+
/**
107+
* @brief Merge another sparse store (same allocator) into this one.
108+
* @param other store; its counts are added here.
109+
*/
110+
void merge(const SparseStore<Allocator>& other);
111+
112+
/**
113+
* @brief Merge a dense store (same allocator) into this one.
114+
* @tparam Derived type of the other dense store.
115+
* @param other store; its counts are added here.
116+
*/
117+
template<class Derived>
118+
void merge(const DenseStore<Derived, Allocator>& other);
119+
120+
121+
bool is_empty() const;
122+
123+
/**
124+
* @brief Total count across all bins.
125+
*/
126+
double get_total_count() const;
127+
128+
/**
129+
* This method serializes the store into a given stream in a binary form
130+
* @param os output stream
131+
*/
132+
void serialize(std::ostream& os) const;
133+
134+
/**
135+
* @brief Deserialize the store from a stream (replacing current contents).
136+
* @param is Input stream.
137+
*/
138+
static SparseStore deserialize(std::istream& is);
139+
140+
141+
/**
142+
* Computes size needed to serialize the current state of the sketch.
143+
* @return size in bytes needed to serialize this sketch
144+
*/
145+
int get_serialized_size_bytes() const;
146+
147+
string<Allocator> to_string() const;
148+
/**
149+
* @brief Begin iterator over bins (ascending).
150+
*/
151+
iterator begin() const;
152+
153+
/**
154+
* @brief End iterator over bins (ascending).
155+
*/
156+
iterator end() const;
157+
158+
/**
159+
* @brief Begin reverse iterator over bins (descending).
160+
*/
161+
reverse_iterator rbegin() const;
162+
163+
/**
164+
* @brief End reverse iterator over bins (descending).
165+
*/
166+
reverse_iterator rend() const;
167+
168+
// ---------------- Iterators ----------------
169+
170+
/**
171+
* @class SparseStore::iterator
172+
* @brief Input iterator yielding Bin values in ascending index order.
173+
*
174+
* Stable only while the store is not mutated.
175+
*/
176+
class iterator {
177+
public:
178+
using internal_iterator = typename bins_type::const_iterator;
179+
using iterator_category = std::input_iterator_tag;
180+
using value_type = Bin;
181+
using difference_type = std::ptrdiff_t;
182+
using pointer = Bin*;
183+
using reference = Bin;
184+
185+
/**
186+
* @brief Construct positioned iterator (internal use).
187+
*/
188+
explicit iterator(internal_iterator it);
189+
190+
/**
191+
* @brief Pre-increment.
192+
*/
193+
iterator& operator++();
194+
195+
/**
196+
* @brief Post-increment.
197+
*/
198+
iterator operator++(int);
199+
200+
/**
201+
* @brief Assign from another iterator.
202+
*/
203+
iterator& operator=(const iterator& other);
204+
205+
/**
206+
* @brief Inequality comparison.
207+
*/
208+
bool operator!=(const iterator& other) const;
209+
210+
/**
211+
* @brief Dereference to the current Bin (index, count).
212+
*/
213+
reference operator*() const;
214+
215+
private:
216+
internal_iterator it;
217+
};
218+
/**
219+
* @class SparseStore::reverse_iterator
220+
* @brief Input iterator yielding Bin values in descending index order.
221+
*
222+
* Stable only while the store is not mutated.
223+
*/
224+
class reverse_iterator {
225+
public:
226+
using internal_iterator = typename bins_type::const_reverse_iterator;
227+
using iterator_category = std::input_iterator_tag;
228+
using value_type = Bin;
229+
using difference_type = std::ptrdiff_t;
230+
using pointer = Bin*;
231+
using reference = Bin;
232+
233+
/**
234+
* @brief Construct positioned reverse iterator (internal use).
235+
*/
236+
explicit reverse_iterator(internal_iterator it);
237+
238+
/**
239+
* @brief Pre-increment.
240+
*/
241+
reverse_iterator& operator++();
242+
243+
/**
244+
* @brief Post-increment.
245+
*/
246+
reverse_iterator operator++(int);
247+
248+
/**
249+
* @brief Assign from another reverse iterator.
250+
*/
251+
reverse_iterator& operator=(const reverse_iterator& other);
252+
253+
/**
254+
* @brief Inequality comparison.
255+
*/
256+
bool operator!=(const reverse_iterator& other) const;
257+
258+
/**
259+
* @brief Dereference to the current Bin (index, count).
260+
*/
261+
reference operator*() const;
262+
263+
private:
264+
internal_iterator it;
265+
};
266+
267+
268+
private:
269+
bins_type bins;
270+
};
271+
}
272+
273+
#include "sparse_store_impl.hpp"
274+
275+
#endif //SPARSE_STORE_HPP

0 commit comments

Comments
 (0)