-
Notifications
You must be signed in to change notification settings - Fork 40
Expand file tree
/
Copy pathDataStructures.h
More file actions
206 lines (173 loc) · 4.37 KB
/
Copy pathDataStructures.h
File metadata and controls
206 lines (173 loc) · 4.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
#pragma once
#include "Config.h"
#include <algorithm>
#include <atomic>
#include <vector>
namespace CompactNSearch
{
struct PointID
{
unsigned int point_set_id;
unsigned int point_id;
bool operator==(PointID const& other) const
{
return point_id == other.point_id && point_set_id == other.point_set_id;
}
};
struct HashKey
{
HashKey() = default;
HashKey(int i, int j, int k)
{
this->k[0] = i, this->k[1] = j, this->k[2] = k;
}
HashKey& operator=(HashKey const& other)
{
k[0] = other.k[0];
k[1] = other.k[1];
k[2] = other.k[2];
return *this;
}
bool operator==(HashKey const& other) const
{
return
k[0] == other.k[0] &&
k[1] == other.k[1] &&
k[2] == other.k[2];
}
bool operator!=(HashKey const& other) const
{
return !(*this == other);
}
int k[3];
};
struct HashEntry
{
HashEntry() : n_searching_points(0u)
{
indices.reserve(INITIAL_NUMBER_OF_INDICES);
}
HashEntry(PointID const& id) : n_searching_points(0u)
{
add(id);
}
void add(PointID const& id)
{
indices.push_back(id);
}
void erase(PointID const& id)
{
auto it = std::find(indices.begin(), indices.end(), id);
if (it != indices.end())
indices.erase(it);
}
unsigned int n_indices() const
{
return static_cast<unsigned int>(indices.size());
}
std::vector<PointID> indices;
unsigned int n_searching_points;
};
struct SpatialHasher
{
std::size_t operator()(HashKey const& k) const
{
return static_cast<size_t>(
static_cast<int64_t>(73856093) * static_cast<int64_t>(k.k[0]) ^
static_cast<int64_t>(19349663) * static_cast<int64_t>(k.k[1]) ^
static_cast<int64_t>(83492791) * static_cast<int64_t>(k.k[2]));
}
};
class Spinlock
{
public:
void lock()
{
while (m_lock.test_and_set(std::memory_order_acquire));
}
void unlock()
{
m_lock.clear(std::memory_order_release);
}
Spinlock() = default;
Spinlock(Spinlock const& other) {};
Spinlock& operator=(Spinlock const& other) { return *this; }
private:
std::atomic_flag m_lock = ATOMIC_FLAG_INIT;
};
class ActivationTable
{
private:
std::vector<std::vector<unsigned char>> m_table;
public:
bool operator==(ActivationTable const& other) const
{
return m_table == other.m_table;
}
bool operator!=(ActivationTable const& other) const
{
return !(m_table == other.m_table);
}
/** Add point set. If search_neighbors is true, neighbors in all other point sets are searched.
* If find_neighbors is true, the new point set is activated in the neighborhood search of all other point sets.
*/
void add_point_set(bool search_neighbors = true, bool find_neighbors = true)
{
// add column to each row
auto size = m_table.size();
for (auto i = 0u; i < size; i++)
{
m_table[i].resize(size + 1);
m_table[i][size] = static_cast<unsigned char>(find_neighbors);
}
// add new row
m_table.resize(size + 1);
m_table[size].resize(size + 1);
for (auto i = 0u; i < size + 1; i++)
m_table[size][i] = static_cast<unsigned char>(search_neighbors);
}
/** Activate/Deactivate that neighbors in point set index2 are found when searching for neighbors of point set index1.
*/
void set_active(unsigned int index1, unsigned int index2, bool active)
{
m_table[index1][index2] = static_cast<unsigned char>(active);
}
/** Activate/Deactivate all point set pairs containing the given index. If search_neighbors is true, neighbors in all other point sets are searched.
* If find_neighbors is true, the new point set is activated in the neighborhood search of all other point sets.
*/
void set_active(unsigned int index, bool search_neighbors = true, bool find_neighbors = true)
{
auto size = m_table.size();
for (auto i = 0u; i < size; i++)
{
m_table[i][index] = static_cast<unsigned char>(find_neighbors);
m_table[index][i] = static_cast<unsigned char>(search_neighbors);
}
m_table[index][index] = static_cast<unsigned char>(search_neighbors && find_neighbors);
}
/** Activate/Deactivate all point set pairs.
*/
void set_active(bool active)
{
auto size = m_table.size();
for (auto i = 0u; i < size; i++)
for (auto j = 0u; j < size; j++)
m_table[i][j] = static_cast<unsigned char>(active);
}
bool is_active(unsigned int index1, unsigned int index2) const
{
return m_table[index1][index2] != 0;
}
bool is_searching_neighbors(unsigned int const index) const
{
for (auto i = 0u; i < m_table[index].size(); i++)
{
if (m_table[index][i])
{
return true;
}
}
return false;
}
};
}