private HSTNode BuildTreeParallel(int bit, int left, int right, int level = 0) { if (bit < 0 || right - left <= 1) { return(null); } int[] dids = new int[(1 << D) + 1]; dids[0] = left; dids[1 << D] = right; SortAndDivide(dids, bit, 0, 1 << D); HSTNode[] children = new HSTNode[1 << D]; if (level < 3 && right - left > 2048) { Parallel.For(0, 1 << D, i => children[i] = BuildTreeParallel(bit - D, dids[i], dids[i + 1], level + 1)); } else { for (int i = (1 << D) - 1; i >= 0; i--) { children[i] = BuildTreeSequential(bit - D, dids[i], dids[i + 1]); } } return(new HSTNode(this, dids, children)); }
private HSTNode BuildTreePresorted(int bit, int left, int right) { if (bit < 0 || right - left <= 1) { return(null); } int[] dids = new int[(1 << D) + 1]; dids[0] = left; dids[1 << D] = right; dids = FindDivision(dids, bit, 0, 1 << D); HSTNode[] children = new HSTNode[1 << D]; for (int i = (1 << D) - 1; i >= 0; i--) { children[i] = BuildTreePresorted(bit - D, dids[i], dids[i + 1]); } return(new HSTNode(this, dids, children)); }
public void RebuildTree(bool presort) { size = 2 * AbsoluteMax(); Parallel.For(0, N, i => { ids[i] = i; ulong hash = 0; for (int j = 0; j < D; j++) { ulong bin = (ulong)(maxv * (points[j + i * D] / size + 0.5)); //normalization should be <0, 1) if (bin == maxv) { bin--; //fix normalization } for (int k = j; bin != 0; k += 8 * D) { hash += morton[bin & 0xFF] << k; bin >>= 8; } } hashes[i] = hash; }); if (presort) { Array.Sort(hashes, ids); root = BuildTreePresorted(bit4dim * D - 1, 0, hashes.Length); } else { root = BuildTreeParallel(bit4dim * D - 1, 0, hashes.Length); } root.Fill(size / 2.0); }