53 : m_r(r), m_id(id), m_len(len), m_pData(pData), m_s(s)
119 : m_bInsertionPhase(true), m_u32PageSize(u32PageSize),
120 m_u32BufferPages(u32BufferPages), m_u64TotalEntries(0), m_stI(0)
126 for (m_stI = 0; m_stI < m_buffer.size(); ++m_stI)
delete m_buffer[m_stI];
131 if (m_bInsertionPhase ==
false)
134 m_buffer.push_back(r);
139 if (m_buffer.size() >= m_u32PageSize * m_u32BufferPages)
143 for (
size_t j = 0; j < m_buffer.size(); ++j)
145 m_buffer[j]->storeToFile(*tf);
149 tf->rewindForReading();
150 m_runs.push_back(std::shared_ptr<Tools::TemporaryFile>(tf));
156 if (m_bInsertionPhase ==
false)
163 m_bInsertionPhase =
false;
167 if (m_buffer.size() > 0)
173 for (
size_t j = 0; j < m_buffer.size(); ++j)
175 m_buffer[j]->storeToFile(*tf);
179 tf->rewindForReading();
180 m_runs.push_back(std::shared_ptr<Tools::TemporaryFile>(tf));
183 if (m_runs.size() == 1)
185 m_sortedFile = m_runs.front();
191 while (m_runs.size() > 1)
194 std::vector<std::shared_ptr<Tools::TemporaryFile> > buckets;
195 std::vector<std::queue<Record*> > buffers;
199 std::list<std::shared_ptr<Tools::TemporaryFile> >::iterator it = m_runs.begin();
200 for (uint32_t i = 0; i < (std::min)(static_cast<uint32_t>(m_runs.size()), m_u32BufferPages); ++i)
202 buckets.push_back(*it);
203 buffers.emplace_back();
208 pq.push(PQEntry(r, i));
210 for (uint32_t j = 0; j < m_u32PageSize - 1; ++j)
217 buffers.back().push(r);
231 PQEntry e = pq.top(); pq.pop();
232 e.
m_r->storeToFile(*tf);
235 if (! buckets[e.m_u32Index]->eof() && buffers[e.m_u32Index].empty())
237 for (uint32_t j = 0; j < m_u32PageSize; ++j)
243 buffers[e.m_u32Index].push(r);
253 if (! buffers[e.m_u32Index].empty())
255 e.
m_r = buffers[e.m_u32Index].front();
256 buffers[e.m_u32Index].pop();
261 tf->rewindForReading();
264 uint32_t u32Count = std::min(static_cast<uint32_t>(m_runs.size()), m_u32BufferPages);
265 for (uint32_t i = 0; i < u32Count; ++i)
270 if (m_runs.size() == 0)
277 m_runs.push_back(tf);
282 m_bInsertionPhase =
false;
287 if (m_bInsertionPhase ==
true)
292 if (m_sortedFile.get() ==
nullptr)
294 if (m_stI < m_buffer.size())
296 ret = m_buffer[m_stI];
297 m_buffer[m_stI] =
nullptr;
314 return m_u64TotalEntries;
326 uint32_t numberOfPages
330 "RTree::BulkLoader::bulkLoadUsingSTR: Empty data stream given." 333 NodePtr n = pTree->readNode(pTree->m_rootID);
334 pTree->deleteNode(n.
get());
337 std::cerr <<
"RTree::BulkLoader: Sorting data." << std::endl;
340 std::shared_ptr<ExternalSorter> es = std::shared_ptr<ExternalSorter>(
new ExternalSorter(pageSize, numberOfPages));
347 "bulkLoadUsingSTR: RTree bulk load expects SpatialIndex::RTree::Data entries." 356 pTree->m_stats.m_u64Data = es->getTotalEntries();
364 std::cerr <<
"RTree::BulkLoader: Building level " << level << std::endl;
367 pTree->m_stats.m_nodesInLevel.push_back(0);
369 std::shared_ptr<ExternalSorter> es2 = std::shared_ptr<ExternalSorter>(
new ExternalSorter(pageSize, numberOfPages));
370 createLevel(pTree, es, 0, bleaf, bindex, level++, es2, pageSize, numberOfPages);
373 if (es->getTotalEntries() == 1)
break;
377 pTree->m_stats.m_u32TreeHeight = level;
378 pTree->storeHeader();
383 std::shared_ptr<ExternalSorter> es,
388 std::shared_ptr<ExternalSorter> es2,
390 uint32_t numberOfPages
392 uint64_t b = (level == 0) ? bleaf : bindex;
393 uint64_t P =
static_cast<uint64_t
>(std::ceil(static_cast<double>(es->getTotalEntries()) / static_cast<double>(b)));
394 uint64_t S =
static_cast<uint64_t
>(std::ceil(std::sqrt(static_cast<double>(P))));
396 if (S == 1 || dimension == pTree->m_dimension - 1 || S * b == es->getTotalEntries())
398 std::vector<ExternalSorter::Record*> node;
406 if (node.size() == b)
408 Node* n = createNode(pTree, node, level);
412 pTree->m_rootID = n->m_identifier;
420 Node* n = createNode(pTree, node, level);
423 pTree->m_rootID = n->m_identifier;
434 std::shared_ptr<ExternalSorter> es3 = std::shared_ptr<ExternalSorter>(
new ExternalSorter(pageSize, numberOfPages));
436 for (uint64_t i = 0; i < S * b; ++i)
438 try { pR = es->getNextRecord(); }
440 pR->
m_s = dimension + 1;
444 createLevel(pTree, es3, dimension + 1, bleaf, bindex, level, es2, pageSize, numberOfPages);
453 if (level == 0) n =
new Leaf(pTree, -1);
454 else n =
new Index(pTree, -1, level);
456 for (
size_t cChild = 0; cChild < e.size(); ++cChild)
458 n->insertEntry(e[cChild]->m_len, e[cChild]->m_pData, e[cChild]->m_r, e[cChild]->m_id);
459 e[cChild]->m_pData =
nullptr;
void bulkLoadUsingSTR(RTree *pTree, IDataStream &stream, uint32_t bindex, uint32_t bleaf, uint32_t pageSize, uint32_t numberOfPages)
bool operator<(const Record &r) const
Node * createNode(RTree *pTree, std::vector< ExternalSorter::Record *> &e, uint32_t level)
void storeToFile(Tools::TemporaryFile &f)
ExternalSorter(uint32_t u32PageSize, uint32_t u32BufferPages)
IData * getNext() override=0
virtual ~ExternalSorter()
void createLevel(RTree *pTree, std::shared_ptr< ExternalSorter > es, uint32_t dimension, uint32_t indexSize, uint32_t leafSize, uint32_t level, std::shared_ptr< ExternalSorter > es2, uint32_t pageSize, uint32_t numberOfPages)
uint64_t getTotalEntries() const
void loadFromFile(Tools::TemporaryFile &f)