@@ -92,21 +92,19 @@ struct grid {
9292 cells = newA (cellT, cellCapacity);
9393 nbrCache = newA (cellBuf*, cellCapacity);
9494 cacheLocks = (std::mutex*) malloc (cellCapacity * sizeof (std::mutex));
95- parallel_for (0 , cellCapacity, [&](intT i) {
96- new (&cacheLocks[i]) std::mutex ();
97- nbrCache[i] = NULL ;
98- cells[i].init ();
99- });
10095 numCells = 0 ;
10196
10297 myHash = new cellHashT (pMinn, r);
103- table = new tableT (cellMax*2 , cellHash<dim, objT>(myHash));// todo load
98+ // Hash table sized for expected number of cells, with safety rebuild
99+ // in insertParallel if numCells exceeds the estimate.
100+ intT tableHint = std::max ((intT)2048 , cellMax / 4 );
101+ table = new tableT (tableHint, cellHash<dim, objT>(myHash));
104102 }
105103
106104 ~grid () {
107105 free (cells);
108106 free (cacheLocks);
109- parallel_for (0 , cellCapacity , [&](intT i) {
107+ parallel_for (0 , numCells , [&](intT i) {
110108 if (nbrCache[i]) delete nbrCache[i];
111109 });
112110 free (nbrCache);
@@ -239,6 +237,19 @@ struct grid {
239237 if (numCells > cellCapacity) {
240238 cout << " error, grid insert exceeded cell capacity, abort()" << endl;abort ();}
241239
240+ // Rebuild hash table if initial estimate was too small
241+ if (numCells > cellCapacity / 8 ) {
242+ table->del (); delete table;
243+ table = new tableT (numCells * 2 , cellHash<dim, objT>(myHash));
244+ }
245+
246+ // Initialize only the cells that will actually be used
247+ parallel_for (0 , numCells, [&](intT i) {
248+ new (&cacheLocks[i]) std::mutex ();
249+ nbrCache[i] = NULL ;
250+ cells[i].init ();
251+ });
252+
242253 parallel_for (0 , nn, [&](intT i) {
243254 if (flag[i] != flag[i+1 ]) {
244255 auto c = &cells[flag[i]];
0 commit comments