Skip to content

Commit cf01f87

Browse files
committed
Fix minor memory leak
1 parent 6f9da83 commit cf01f87

File tree

1 file changed

+40
-15
lines changed

1 file changed

+40
-15
lines changed

include/dbscan/grid.h

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
#pragma once
2525

26+
#include <mutex>
2627
#include "cell.h"
2728
#include "point.h"
2829
#include "shared.h"
@@ -77,6 +78,7 @@ struct grid {
7778
treeT* tree=NULL;
7879
intT totalPoints;
7980
cellBuf **nbrCache;
81+
std::mutex* cacheLocks;
8082

8183
/**
8284
* Grid constructor.
@@ -89,10 +91,12 @@ struct grid {
8991

9092
cells = newA(cellT, cellCapacity);
9193
nbrCache = newA(cellBuf*, cellCapacity);
94+
cacheLocks = (std::mutex*) malloc(cellCapacity * sizeof(std::mutex));
9295
parallel_for(0, cellCapacity, [&](intT i) {
93-
nbrCache[i] = NULL;
94-
cells[i].init();
95-
});
96+
new (&cacheLocks[i]) std::mutex();
97+
nbrCache[i] = NULL;
98+
cells[i].init();
99+
});
96100
numCells = 0;
97101

98102
myHash = new cellHashT(pMinn, r);
@@ -101,9 +105,10 @@ struct grid {
101105

102106
~grid() {
103107
free(cells);
104-
parallel_for(0, numCells, [&](intT i) {
105-
if(nbrCache[i]) delete nbrCache[i];
106-
});
108+
free(cacheLocks);
109+
parallel_for(0, cellCapacity, [&](intT i) {
110+
if(nbrCache[i]) delete nbrCache[i];
111+
});
107112
free(nbrCache);
108113
if(myHash) delete myHash;
109114
if(table) {
@@ -141,14 +146,24 @@ struct grid {
141146
}
142147
}
143148
return false;};//todo, optimize
144-
if (nbrCache[bait-cells]) {
145-
auto accum = nbrCache[bait-cells];
149+
int idx = bait - cells;
150+
if (nbrCache[idx]) {
151+
auto accum = nbrCache[idx];
146152
for (auto accum_i : *accum) {
147153
if(fWrap(accum_i)) break;
148154
}
149155
} else {
150-
floatT hop = sqrt(dim + 3) * 1.0000001;
151-
nbrCache[bait-cells] = tree->rangeNeighbor(bait, r * hop, fStop, fWrap, true, nbrCache[bait-cells]);
156+
// wait for other threads to do their thing then try again
157+
std::lock_guard<std::mutex> lock(cacheLocks[idx]);
158+
if (nbrCache[idx]) {
159+
auto accum = nbrCache[idx];
160+
for (auto accum_i : *accum) {
161+
if (fWrap(accum_i)) break;
162+
}
163+
} else {
164+
floatT hop = sqrt(dim + 3) * 1.0000001;
165+
nbrCache[idx] = tree->rangeNeighbor(bait, r * hop, fStop, fWrap, true, nbrCache[idx]);
166+
}
152167
}
153168
}
154169

@@ -160,14 +175,24 @@ struct grid {
160175
return f(cell);
161176
return false;
162177
};
163-
if (nbrCache[bait-cells]) {
164-
auto accum = nbrCache[bait-cells];
178+
int idx = bait - cells;
179+
if (nbrCache[idx]) {
180+
auto accum = nbrCache[idx];
165181
for (auto accum_i : *accum) {
166-
if(fWrap(accum_i)) break;
182+
if (fWrap(accum_i)) break;
167183
}
168184
} else {
169-
floatT hop = sqrt(dim + 3) * 1.0000001;
170-
nbrCache[bait-cells] = tree->rangeNeighbor(bait, r * hop, fStop, fWrap, true, nbrCache[bait-cells]);
185+
// wait for other threads to do their thing then try again
186+
std::lock_guard<std::mutex> lock(cacheLocks[idx]);
187+
if (nbrCache[idx]) {
188+
auto accum = nbrCache[idx];
189+
for (auto accum_i : *accum) {
190+
if (fWrap(accum_i)) break;
191+
}
192+
} else {
193+
floatT hop = sqrt(dim + 3) * 1.0000001;
194+
nbrCache[bait-cells] = tree->rangeNeighbor(bait, r * hop, fStop, fWrap, true, nbrCache[idx]);
195+
}
171196
}
172197
}
173198

0 commit comments

Comments
 (0)