47 NodePtr Index::chooseSubtree(
const TimeRegion& mbr, uint32_t insertionLevel, std::stack<id_type>& pathBuffer)
49 if (m_level == insertionLevel)
return NodePtr(
this, &(m_pTree->m_indexPool));
51 pathBuffer.push(m_identifier);
55 switch (m_pTree->m_treeVariant)
59 child = findLeastEnlargement(mbr);
65 child = findLeastOverlap(mbr);
69 child = findLeastEnlargement(mbr);
75 assert (child != std::numeric_limits<uint32_t>::max());
77 NodePtr n = m_pTree->readNode(m_pIdentifier[child]);
78 NodePtr ret = n->chooseSubtree(mbr, insertionLevel, pathBuffer);
87 pathBuffer.push(m_identifier);
89 for (uint32_t cChild = 0; cChild < m_children; ++cChild)
92 if (m_ptrMBR[cChild]->m_endTime < std::numeric_limits<double>::max())
continue;
96 if (m_ptrMBR[cChild]->containsRegion(mbr))
98 NodePtr n = m_pTree->readNode(m_pIdentifier[cChild]);
99 NodePtr l = n->findLeaf(mbr,
id, pathBuffer);
101 if (l.
get() !=
nullptr)
return l;
114 ++(m_pTree->m_stats.m_u64Splits);
116 std::vector<uint32_t> g1, g2;
118 switch (m_pTree->m_treeVariant)
122 rtreeSplit(dataLength, pData, mbr,
id, g1, g2, mbr2, id2, bInsertMbr2);
125 rstarSplit(dataLength, pData, mbr,
id, g1, g2, mbr2, id2, bInsertMbr2);
131 pLeft = m_pTree->m_indexPool.acquire();
132 pRight = m_pTree->m_indexPool.acquire();
134 if (pLeft.
get() ==
nullptr) pLeft =
NodePtr(
new Index(m_pTree, m_identifier, m_level), &(m_pTree->m_indexPool));
135 if (pRight.
get() ==
nullptr) pRight =
NodePtr(
new Index(m_pTree, -1, m_level), &(m_pTree->m_indexPool));
137 pLeft->m_nodeMBR = m_pTree->m_infiniteRegion;
138 pRight->m_nodeMBR = m_pTree->m_infiniteRegion;
142 for (cIndex = 0; cIndex < g1.size(); ++cIndex)
144 pLeft->insertEntry(0,
nullptr, *(m_ptrMBR[g1[cIndex]]), m_pIdentifier[g1[cIndex]]);
147 for (cIndex = 0; cIndex < g2.size(); ++cIndex)
149 pRight->insertEntry(0,
nullptr, *(m_ptrMBR[g2[cIndex]]), m_pIdentifier[g2[cIndex]]);
153 uint32_t Index::findLeastEnlargement(
const TimeRegion& r)
const
155 double area = std::numeric_limits<double>::max();
156 uint32_t best = std::numeric_limits<uint32_t>::max();
160 for (uint32_t cChild = 0; cChild < m_children; ++cChild)
163 if (m_ptrMBR[cChild]->m_endTime <= r.
m_startTime)
continue;
167 double a = m_ptrMBR[cChild]->getArea();
176 enl > area - std::numeric_limits<double>::epsilon() &&
177 enl < area + std::numeric_limits<double>::epsilon())
179 if (a < m_ptrMBR[best]->getArea()) best = cChild;
186 uint32_t Index::findLeastOverlap(
const TimeRegion& r)
const
188 OverlapEntry** entries =
new OverlapEntry*[m_children];
190 double leastOverlap = std::numeric_limits<double>::max();
191 double me = std::numeric_limits<double>::max();
192 OverlapEntry* best =
nullptr;
193 uint32_t cLiveEntries = 0;
196 for (uint32_t cChild = 0; cChild < m_children; ++cChild)
198 if (m_ptrMBR[cChild]->m_endTime <= r.
m_startTime)
continue;
202 entries[cLiveEntries] =
new OverlapEntry();
206 for (uint32_t i = 0; i < cLiveEntries; ++i)
delete entries[i];
211 entries[cLiveEntries]->m_index = cChild;
212 entries[cLiveEntries]->m_original = m_ptrMBR[cChild];
213 entries[cLiveEntries]->m_combined = m_pTree->m_regionPool.acquire();
214 m_ptrMBR[cChild]->getCombinedRegion(*(entries[cLiveEntries]->m_combined), r);
215 entries[cLiveEntries]->m_oa = entries[cLiveEntries]->m_original->getArea();
216 entries[cLiveEntries]->m_ca = entries[cLiveEntries]->m_combined->getArea();
217 entries[cLiveEntries]->m_enlargement = entries[cLiveEntries]->m_ca - entries[cLiveEntries]->m_oa;
219 if (entries[cLiveEntries]->m_enlargement < me)
221 me = entries[cLiveEntries]->m_enlargement;
222 best = entries[cLiveEntries];
224 else if (entries[cLiveEntries]->m_enlargement == me && entries[cLiveEntries]->m_oa < best->m_oa)
226 best = entries[cLiveEntries];
231 if (me < -std::numeric_limits<double>::epsilon() || me > std::numeric_limits<double>::epsilon())
233 uint32_t cIterations;
235 if (cLiveEntries > m_pTree->m_nearMinimumOverlapFactor)
238 ::qsort(entries, cLiveEntries,
239 sizeof(OverlapEntry*),
240 OverlapEntry::compareEntries);
241 assert(entries[0]->m_enlargement <= entries[m_children - 1]->m_enlargement);
243 cIterations = m_pTree->m_nearMinimumOverlapFactor;
247 cIterations = cLiveEntries;
251 for (uint32_t cIndex = 0; cIndex < cIterations; ++cIndex)
254 OverlapEntry* e = entries[cIndex];
256 for (uint32_t cChild = 0; cChild < cLiveEntries; ++cChild)
258 if (cIndex != cChild)
260 double f = e->m_combined->getIntersectingArea(*(entries[cChild]->m_original));
261 if (f != 0.0) dif += f - e->m_original->getIntersectingArea(*(entries[cChild]->m_original));
265 if (dif < leastOverlap)
270 else if (dif == leastOverlap)
272 if (e->m_enlargement == best->m_enlargement)
275 if (e->m_original->getArea() < best->m_original->getArea()) best = e;
280 if (e->m_enlargement < best->m_enlargement) best = e;
286 uint32_t ret = best->m_index;
288 for (uint32_t cChild = 0; cChild < cLiveEntries; ++cChild)
290 delete entries[cChild];
297 void Index::adjustTree(
Node* n, std::stack<id_type>& pathBuffer)
299 ++(m_pTree->m_stats.m_u64Adjustments);
303 for (child = 0; child < m_children; ++child)
305 if (m_pIdentifier[child] == n->m_identifier)
break;
311 bool bContained = m_nodeMBR.containsRegion(n->m_nodeMBR);
312 bool bTouches = m_nodeMBR.touchesRegion(*(m_ptrMBR[child]));
313 bool bRecompute = (! bContained || (bTouches && m_pTree->m_bTightMBRs));
316 double st = m_ptrMBR[child]->m_startTime;
317 double en = m_ptrMBR[child]->m_endTime;
318 *(m_ptrMBR[child]) = n->m_nodeMBR;
320 m_ptrMBR[child]->m_endTime = en;
326 for (uint32_t cDim = 0; cDim < m_nodeMBR.m_dimension; ++cDim)
328 m_nodeMBR.m_pLow[cDim] = std::numeric_limits<double>::max();
329 m_nodeMBR.m_pHigh[cDim] = -std::numeric_limits<double>::max();
331 for (uint32_t cChild = 0; cChild < m_children; ++cChild)
333 m_nodeMBR.m_pLow[cDim] = std::min(m_nodeMBR.m_pLow[cDim], m_ptrMBR[cChild]->m_pLow[cDim]);
334 m_nodeMBR.m_pHigh[cDim] = std::max(m_nodeMBR.m_pHigh[cDim], m_ptrMBR[cChild]->m_pHigh[cDim]);
339 m_pTree->writeNode(
this);
341 if (bRecompute && (! pathBuffer.empty()))
343 id_type cParent = pathBuffer.top(); pathBuffer.pop();
344 NodePtr ptrN = m_pTree->readNode(cParent);
346 p->adjustTree(
this, pathBuffer);
350 void Index::adjustTree(
Node* n,
Node* nn, std::stack<id_type>& pathBuffer)
352 ++(m_pTree->m_stats.m_u64Adjustments);
355 uint32_t child, child2 = m_capacity;
356 for (child = 0; child < m_children; ++child)
358 if (m_pIdentifier[child] == nn->m_identifier) child2 = child;
359 if (m_pIdentifier[child] == n->m_identifier)
break;
362 if (child2 == m_capacity)
364 for (child2 = child + 1; child2 < m_children; ++child2)
366 if (m_pIdentifier[child2] == nn->m_identifier)
break;
374 bool b1 = m_nodeMBR.containsRegion(n->m_nodeMBR);
375 bool b2 = m_nodeMBR.touchesRegion(*(m_ptrMBR[child]));
376 bool b3 = m_nodeMBR.touchesRegion(*(m_ptrMBR[child2]));
377 bool bRecompute = (! b1) || ((b2 || b3) && m_pTree->m_bTightMBRs);
380 double st = m_ptrMBR[child]->m_startTime;
381 double en = m_ptrMBR[child]->m_endTime;
382 *(m_ptrMBR[child]) = n->m_nodeMBR;
384 m_ptrMBR[child]->m_endTime = en;
386 st = m_ptrMBR[child2]->m_startTime;
387 en = m_ptrMBR[child2]->m_endTime;
388 *(m_ptrMBR[child2]) = nn->m_nodeMBR;
390 m_ptrMBR[child2]->m_endTime = en;
396 for (uint32_t cDim = 0; cDim < m_nodeMBR.m_dimension; ++cDim)
398 m_nodeMBR.m_pLow[cDim] = std::numeric_limits<double>::max();
399 m_nodeMBR.m_pHigh[cDim] = -std::numeric_limits<double>::max();
401 for (uint32_t cChild = 0; cChild < m_children; ++cChild)
403 m_nodeMBR.m_pLow[cDim] = std::min(m_nodeMBR.m_pLow[cDim], m_ptrMBR[cChild]->m_pLow[cDim]);
404 m_nodeMBR.m_pHigh[cDim] = std::max(m_nodeMBR.m_pHigh[cDim], m_ptrMBR[cChild]->m_pHigh[cDim]);
409 m_pTree->writeNode(
this);
411 if (bRecompute && (! pathBuffer.empty()))
413 id_type cParent = pathBuffer.top(); pathBuffer.pop();
414 NodePtr ptrN = m_pTree->readNode(cParent);
416 p->adjustTree(
this, pathBuffer);
virtual void getCombinedRegion(Region &out, const Region &in) const
double getArea() const override
Tools::PoolPointer< Node > NodePtr