Visual Computing Library
Loading...
Searching...
No Matches
hash_table_grid.h
1/*****************************************************************************
2 * VCLib *
3 * Visual Computing Library *
4 * *
5 * Copyright(C) 2021-2025 *
6 * Visual Computing Lab *
7 * ISTI - Italian National Research Council *
8 * *
9 * All rights reserved. *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the Mozilla Public License Version 2.0 as published *
13 * by the Mozilla Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * Mozilla Public License Version 2.0 *
20 * (https://www.mozilla.org/en-US/MPL/2.0/) for more details. *
21 ****************************************************************************/
22
23#ifndef VCL_SPACE_COMPLEX_GRID_HASH_TABLE_GRID_H
24#define VCL_SPACE_COMPLEX_GRID_HASH_TABLE_GRID_H
25
26#include "abstract_grid.h"
27#include "regular_grid.h"
28
29#include <set>
30#include <unordered_map>
31
32namespace vcl {
33
49template<typename GridType, typename ValueType, bool AllowDuplicates = true>
51 public AbstractGrid<
52 GridType,
53 ValueType,
54 HashTableGrid<GridType, ValueType, AllowDuplicates>>
55{
56 static_assert(
57 AllowDuplicates || std::equality_comparable<ValueType>,
58 "Not allowing duplicates in a Spatial Data Structures means that "
59 "ValueType must implement operator==.");
60
61 using AbsGrid = AbstractGrid<
62 GridType,
63 ValueType,
65
66 friend AbsGrid;
67
68public:
69 using KeyType = AbsGrid::KeyType;
70
71private:
72 using MapType = std::unordered_multimap<KeyType, ValueType>;
73 using MapValueType = MapType::value_type;
74
75 MapType mMap;
76
77public:
78 using IntersectsCellFunction = AbsGrid::IntersectsCellFunction;
79
80 using Iterator = std::unordered_multimap<KeyType, ValueType>::iterator;
81 using ConstIterator =
82 std::unordered_multimap<KeyType, ValueType>::const_iterator;
83
84 HashTableGrid() {};
85
86 HashTableGrid(const GridType& g) : AbsGrid(g) {}
87
101 template<typename ObjIterator>
103 ObjIterator begin,
104 ObjIterator end,
105 const IntersectsCellFunction& intersects = nullptr) :
106 AbsGrid(begin, end, intersects)
107 {
108 AbsGrid::insert(begin, end);
109 }
110
111 template<Range Rng>
112 HashTableGrid(Rng&& r, const IntersectsCellFunction& intersects = nullptr) :
114 std::ranges::begin(r),
115 std::ranges::end(r),
116 intersects)
117 {
118 }
119
124 bool empty() const { return mMap.empty(); }
125
132 bool cellEmpty(const KeyType& k) const
133 {
134 return mMap.find(k) == mMap.end();
135 }
136
142 std::set<KeyType> nonEmptyCells() const
143 {
144 std::set<KeyType> keys;
145 for (const auto& p : mMap)
146 keys.insert(p.first);
147 return keys;
148 }
149
155 std::size_t countInCell(const KeyType& k) const { return mMap.count(k); }
156
157 std::pair<Iterator, Iterator> valuesInCell(const KeyType& k)
158 {
159 auto p = mMap.equal_range(k);
160 return std::make_pair(Iterator(p.first), Iterator(p.second));
161 }
162
163 std::pair<ConstIterator, ConstIterator> valuesInCell(const KeyType& k) const
164 {
165 auto p = mMap.equal_range(k);
166 return std::make_pair(ConstIterator(p.first), ConstIterator(p.second));
167 }
168
169 void clear() { mMap.clear(); }
170
171 bool eraseAllInCell(const KeyType& k)
172 {
173 std::pair<Iterator, Iterator> range = mMap.equal_range(k);
174 if (range != mMap.end()) {
175 mMap.erase(range.first, range.second);
176 return true;
177 }
178 return false;
179 }
180
181 void eraseInSphere(const Sphere<typename GridType::ScalarType>& s)
182 {
183 std::vector<ConstIterator> toDel = AbsGrid::valuesInSphere(s);
184 for (auto& it : toDel)
185 mMap.erase(it);
186 }
187
188 Iterator begin() { return mMap.begin(); }
189
190 ConstIterator begin() const { return mMap.begin(); }
191
192 Iterator end() { return mMap.end(); }
193
194 ConstIterator end() const { return mMap.end(); }
195
196private:
197 bool insertInCell(const KeyType& k, const ValueType& v)
198 {
199 if constexpr (AllowDuplicates) {
200 mMap.emplace(k, v);
201 return true;
202 }
203 else {
204 auto range = mMap.equal_range(k);
205 bool found = false;
206 for (Iterator ci = range.first; ci != range.second && !found;
207 ++ci) {
208 if (ci->second == v) {
209 found = true;
210 }
211 }
212 if (!found)
213 mMap.emplace(k, v);
214 return !found;
215 }
216 }
217
218 bool eraseInCell(const KeyType& k, const ValueType& v)
219 {
220 bool found = false;
221
222 std::pair<Iterator, Iterator> range = mMap.equal_range(k);
223 for (Iterator ci = range.first; ci != range.second; ++ci) {
224 if (ci->second == v) {
225 found = true;
226 mMap.erase(ci);
227 if constexpr (!AllowDuplicates) {
228 return true;
229 }
230 }
231 }
232 return found;
233 }
234};
235
236/* Specialization Aliases */
237
238template<
239 typename ValueType,
240 typename ScalarType = double,
241 bool AllowDuplicates = true>
242using HashTableGrid2 =
243 HashTableGrid<RegularGrid2<ScalarType>, ValueType, AllowDuplicates>;
244
245template<
246 typename ValueType,
247 typename ScalarType = double,
248 bool AllowDuplicates = true>
249using HashTableGrid3 =
250 HashTableGrid<RegularGrid3<ScalarType>, ValueType, AllowDuplicates>;
251
252} // namespace vcl
253
254#endif // VCL_SPACE_COMPLEX_GRID_HASH_TABLE_GRID_H
The AbstractGrid class describes a generic Spatial Data Structure organized on a regular grid,...
Definition abstract_grid.h:108
bool insert(const ValueType &v)
Inserts the given element in the AbstractGrid.
Definition abstract_grid.h:183
std::function< bool(const typename GridType::BBoxType &, const RemoveCVRefAndPointer< ValueType > &)> IntersectsCellFunction
The IntersectsCellFunction type is a std::function that takes as input a bounding box and a value,...
Definition abstract_grid.h:119
The HashTableGrid class stores N-Dimensional spatial elements (that could be anything on which it can...
Definition hash_table_grid.h:55
std::set< KeyType > nonEmptyCells() const
Returns an std::set containing the cell coordinates of all the cells that contain at least one elemen...
Definition hash_table_grid.h:142
std::size_t countInCell(const KeyType &k) const
Returns the number of elements contained in the given cell.
Definition hash_table_grid.h:155
bool empty() const
Returns true if the HashTableGrid is empty (no elements in it).
Definition hash_table_grid.h:124
HashTableGrid(ObjIterator begin, ObjIterator end, const IntersectsCellFunction &intersects=nullptr)
Creates an HashTableGrid that contains all the elements that can be iterated from begin to end.
Definition hash_table_grid.h:102
bool cellEmpty(const KeyType &k) const
Returns true if the given cell coordinate does not contain elements in it.
Definition hash_table_grid.h:132
A class representing a line segment in n-dimensional space. The class is parameterized by a PointConc...
Definition segment.h:43