53 : m_r(r), m_id(id), m_len(len), m_pData(pData), m_s(s)
75 f.
write(
static_cast<uint64_t
>(m_id));
76 f.
write(m_r.m_dimension);
79 for (uint32_t i = 0; i < m_r.m_dimension; ++i)
81 f.
write(m_r.m_pLow[i]);
82 f.
write(m_r.m_pHigh[i]);
86 if (m_len > 0) f.
write(m_len, m_pData);
94 m_r.makeDimension(dim);
96 for (uint32_t i = 0; i < m_r.m_dimension; ++i)
103 delete[] m_pData; m_pData =
nullptr;
104 if (m_len > 0) f.
readBytes(m_len, &m_pData);
111 : m_bInsertionPhase(true), m_u32PageSize(u32PageSize),
112 m_u32BufferPages(u32BufferPages), m_u64TotalEntries(0), m_stI(0)
118 for (m_stI = 0; m_stI < m_buffer.size(); ++m_stI)
delete m_buffer[m_stI];
123 if (m_bInsertionPhase ==
false)
126 m_buffer.push_back(r);
131 if (m_buffer.size() >= m_u32PageSize * m_u32BufferPages)
135 for (
size_t j = 0; j < m_buffer.size(); ++j)
137 m_buffer[j]->storeToFile(*tf);
142 m_runs.push_back(std::shared_ptr<Tools::TemporaryFile>(tf));
148 if (m_bInsertionPhase ==
false)
155 m_bInsertionPhase =
false;
159 if (m_buffer.size() > 0)
165 for (
size_t j = 0; j < m_buffer.size(); ++j)
167 m_buffer[j]->storeToFile(*tf);
172 m_runs.push_back(std::shared_ptr<Tools::TemporaryFile>(tf));
175 if (m_runs.size() == 1)
177 m_sortedFile = m_runs.front();
183 while (m_runs.size() > 1)
186 std::vector<std::shared_ptr<Tools::TemporaryFile> > buckets;
187 std::vector<std::queue<Record*> > buffers;
191 std::list<std::shared_ptr<Tools::TemporaryFile> >::iterator it = m_runs.begin();
192 for (uint32_t i = 0; i < (std::min)(static_cast<uint32_t>(m_runs.size()), m_u32BufferPages); ++i)
194 buckets.push_back(*it);
195 buffers.emplace_back();
200 pq.push(PQEntry(r, i));
202 for (uint32_t j = 0; j < m_u32PageSize - 1; ++j)
209 buffers.back().push(r);
223 PQEntry e = pq.top(); pq.pop();
224 e.
m_r->storeToFile(*tf);
227 if (! buckets[e.m_u32Index]->eof() && buffers[e.m_u32Index].empty())
229 for (uint32_t j = 0; j < m_u32PageSize; ++j)
235 buffers[e.m_u32Index].push(r);
245 if (! buffers[e.m_u32Index].empty())
247 e.
m_r = buffers[e.m_u32Index].front();
248 buffers[e.m_u32Index].pop();
253 tf->rewindForReading();
256 uint32_t u32Count = std::min(
static_cast<uint32_t
>(m_runs.size()), m_u32BufferPages);
257 for (uint32_t i = 0; i < u32Count; ++i)
262 if (m_runs.size() == 0)
269 m_runs.push_back(tf);
274 m_bInsertionPhase =
false;
279 if (m_bInsertionPhase ==
true)
284 if (m_sortedFile.get() ==
nullptr)
286 if (m_stI < m_buffer.size())
288 ret = m_buffer[m_stI];
289 m_buffer[m_stI] =
nullptr;
306 return m_u64TotalEntries;
318 uint32_t numberOfPages
322 "RTree::BulkLoader::bulkLoadUsingSTR: Empty data stream given."
325 NodePtr n = pTree->readNode(pTree->m_rootID);
326 pTree->deleteNode(n.
get());
328 std::shared_ptr<ExternalSorter> es = std::shared_ptr<ExternalSorter>(
new ExternalSorter(pageSize, numberOfPages));
335 "bulkLoadUsingSTR: RTree bulk load expects SpatialIndex::RTree::Data entries."
344 pTree->m_stats.m_u64Data = es->getTotalEntries();
351 pTree->m_stats.m_nodesInLevel.push_back(0);
353 std::shared_ptr<ExternalSorter> es2 = std::shared_ptr<ExternalSorter>(
new ExternalSorter(pageSize, numberOfPages));
354 createLevel(pTree, es, 0, bleaf, bindex, level++, es2, pageSize, numberOfPages);
357 if (es->getTotalEntries() == 1)
break;
361 pTree->m_stats.m_u32TreeHeight = level;
362 pTree->storeHeader();
367 std::shared_ptr<ExternalSorter> es,
372 std::shared_ptr<ExternalSorter> es2,
374 uint32_t numberOfPages
376 uint64_t b = (level == 0) ? bleaf : bindex;
377 uint64_t P =
static_cast<uint64_t
>(std::ceil(
static_cast<double>(es->getTotalEntries()) /
static_cast<double>(b)));
378 uint64_t S =
static_cast<uint64_t
>(std::ceil(std::sqrt(
static_cast<double>(P))));
380 if (S == 1 || dimension == pTree->m_dimension - 1 || S * b == es->getTotalEntries())
382 std::vector<ExternalSorter::Record*> node;
390 if (node.size() == b)
396 pTree->m_rootID = n->m_identifier;
407 pTree->m_rootID = n->m_identifier;
418 std::shared_ptr<ExternalSorter> es3 = std::shared_ptr<ExternalSorter>(
new ExternalSorter(pageSize, numberOfPages));
420 for (uint64_t i = 0; i < S * b; ++i)
422 try { pR = es->getNextRecord(); }
424 pR->
m_s = dimension + 1;
428 createLevel(pTree, es3, dimension + 1, bleaf, bindex, level, es2, pageSize, numberOfPages);
437 if (level == 0) n =
new Leaf(pTree, -1);
438 else n =
new Index(pTree, -1, level);
440 for (
size_t cChild = 0; cChild < e.size(); ++cChild)
442 n->insertEntry(e[cChild]->m_len, e[cChild]->m_pData, e[cChild]->m_r, e[cChild]->m_id);
443 e[cChild]->m_pData =
nullptr;
IData * getNext() override=0
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)
void bulkLoadUsingSTR(RTree *pTree, IDataStream &stream, uint32_t bindex, uint32_t bleaf, uint32_t pageSize, uint32_t numberOfPages)
Node * createNode(RTree *pTree, std::vector< ExternalSorter::Record * > &e, uint32_t level)
bool operator<(const Record &r) const
void loadFromFile(Tools::TemporaryFile &f)
void storeToFile(Tools::TemporaryFile &f)
ExternalSorter(uint32_t u32PageSize, uint32_t u32BufferPages)
uint64_t getTotalEntries() const
virtual ~ExternalSorter()