42 : m_id(id), m_region(r), m_pData(nullptr), m_dataLength(len)
101 ptr +=
sizeof(uint32_t);
117 uint8_t* regiondata =
nullptr;
122 *data =
new uint8_t[len];
123 uint8_t* ptr = *data;
128 ptr +=
sizeof(uint32_t);
136 memcpy(ptr, regiondata, regionsize);
150 uint32_t indexCapacity,
151 uint32_t leafCapacity,
201 m_pStorageManager(&sm),
202 m_headerID(StorageManager::
NewPage),
205 m_indexCapacity(100),
207 m_nearMinimumOverlapFactor(32),
208 m_splitDistributionFactor(0.4),
209 m_reinsertFactor(0.3),
210 m_strongVersionOverflow(0.8),
212 m_versionUnderflow(0.3),
215 m_bHasVersionCopied(false),
268 mbr->
m_endTime = std::numeric_limits<double>::max();
270 uint8_t* buffer =
nullptr;
274 buffer =
new uint8_t[len];
275 memcpy(buffer, pData, len);
278 insertData_impl(len, buffer, *mbr,
id);
299 bool ret = deleteData_impl(*mbr,
id);
350 id_type next = m_roots[m_roots.size() - 1].m_id;
454 m_readNodeCommands.push_back(std::shared_ptr<ICommand>(pCommand));
457 m_writeNodeCommands.push_back(std::shared_ptr<ICommand>(pCommand));
460 m_deleteNodeCommands.push_back(std::shared_ptr<ICommand>(pCommand));
468 std::stack<ValidateEntry> st;
469 std::set<id_type> visitedEntries;
470 uint32_t degenerateEntries = 0;
472 for (uint32_t cRoot = 0; cRoot < m_roots.size(); ++cRoot)
474 NodePtr root = readNode(m_roots[cRoot].m_id);
476 if (root->m_level != m_stats.m_treeHeight[cRoot] - 1)
478 std::cerr <<
"Invalid tree height." << std::endl;
482 ValidateEntry e(0, root->m_nodeMBR, root);
483 e.m_bIsDead = (root->m_nodeMBR.
m_endTime < std::numeric_limits<double>::max()) ?
true :
false;
489 ValidateEntry e = st.top(); st.pop();
491 std::set<id_type>::iterator itSet = visitedEntries.find(e.m_pNode->m_identifier);
492 if (itSet == visitedEntries.end())
494 visitedEntries.insert(e.m_pNode->m_identifier);
495 if (e.m_pNode->m_nodeMBR.m_startTime == e.m_pNode->m_nodeMBR.m_endTime) ++degenerateEntries;
499 tmpRegion = m_infiniteRegion;
501 for (uint32_t cDim = 0; cDim < tmpRegion.
m_dimension; ++cDim)
503 for (uint32_t cChild = 0; cChild < e.m_pNode->m_children; ++cChild)
505 tmpRegion.
m_pLow[cDim] = std::min(tmpRegion.
m_pLow[cDim], e.m_pNode->m_ptrMBR[cChild]->m_pLow[cDim]);
506 tmpRegion.
m_pHigh[cDim] = std::max(tmpRegion.
m_pHigh[cDim], e.m_pNode->m_ptrMBR[cChild]->m_pHigh[cDim]);
510 tmpRegion.
m_startTime = e.m_pNode->m_nodeMBR.m_startTime;
511 tmpRegion.
m_endTime = e.m_pNode->m_nodeMBR.m_endTime;
512 if (! (tmpRegion == e.m_pNode->m_nodeMBR))
514 std::cerr <<
"Invalid parent information." << std::endl;
521 tmpRegion.
m_endTime = e.m_parentMBR.m_endTime;
522 if (! (tmpRegion == e.m_parentMBR))
524 std::cerr <<
"Error in parent (Node id: " << e.m_pNode->m_identifier <<
", Parent id: " << e.m_parentID <<
")." << std::endl;
529 if (e.m_pNode->m_level != 0)
531 for (uint32_t cChild = 0; cChild < e.m_pNode->m_children; ++cChild)
533 NodePtr ptrN = readNode(e.m_pNode->m_pIdentifier[cChild]);
536 (e.m_pNode->m_ptrMBR[cChild]->m_endTime < std::numeric_limits<double>::max() || e.m_bIsDead) ?
true :
false;
540 if (bIsDead) ptrN->m_nodeMBR.
m_endTime = e.m_pNode->m_ptrMBR[cChild]->m_endTime;
542 ValidateEntry tmpEntry(e.m_pNode->m_identifier, *(e.m_pNode->m_ptrMBR[cChild]), ptrN);
543 tmpEntry.m_bIsDead = bIsDead;
590 throw Tools::IllegalArgumentException(
"initNew: Property FillFactor must be Tools::VT_DOUBLE and in (0.0, 1.0) for RSTAR, (0.0, 0.5) for LINEAR and QUADRATIC");
620 throw Tools::IllegalArgumentException(
"initNew: Property NearMinimumOverlapFactor must be Tools::VT_ULONG and less than both index and leaf capacities");
733 m_stats.m_treeHeight.push_back(1);
734 m_stats.m_nodesInLevel.push_back(1);
737 root.m_nodeMBR.m_startTime = 0.0;
738 root.m_nodeMBR.m_endTime = std::numeric_limits<double>::max();
740 m_roots.emplace_back(root.m_identifier, root.m_nodeMBR.m_startTime, root.m_nodeMBR.m_endTime);
769 throw Tools::IllegalArgumentException(
"initOld: Property NearMinimumOverlapFactor must be Tools::VT_ULONG and less than both index and leaf capacities");
842 void SpatialIndex::MVRTree::MVRTree::storeHeader()
844 const uint32_t headerSize =
846 static_cast<uint32_t>(m_roots.size())
847 * (
sizeof(
id_type) + 2 *
sizeof(double)) +
863 static_cast<uint32_t>(m_stats.m_treeHeight.size())
870 static_cast<uint32_t
>(m_stats.m_nodesInLevel.size())
873 uint8_t* header =
new uint8_t[headerSize];
874 uint8_t* ptr = header;
876 uint32_t u32I =
static_cast<uint32_t
>(m_roots.size());
877 memcpy(ptr, &u32I,
sizeof(uint32_t));
878 ptr +=
sizeof(uint32_t);
880 for (
size_t cIndex = 0; cIndex < m_roots.size(); ++cIndex)
882 RootEntry& e = m_roots[cIndex];
883 memcpy(ptr, &(e.m_id),
sizeof(
id_type));
885 memcpy(ptr, &(e.m_startTime),
sizeof(
double));
886 ptr +=
sizeof(double);
887 memcpy(ptr, &(e.m_endTime),
sizeof(
double));
888 ptr +=
sizeof(double);
893 memcpy(ptr, &m_fillFactor,
sizeof(
double));
894 ptr +=
sizeof(double);
895 memcpy(ptr, &m_indexCapacity,
sizeof(uint32_t));
896 ptr +=
sizeof(uint32_t);
897 memcpy(ptr, &m_leafCapacity,
sizeof(uint32_t));
898 ptr +=
sizeof(uint32_t);
899 memcpy(ptr, &m_nearMinimumOverlapFactor,
sizeof(uint32_t));
900 ptr +=
sizeof(uint32_t);
901 memcpy(ptr, &m_splitDistributionFactor,
sizeof(
double));
902 ptr +=
sizeof(double);
903 memcpy(ptr, &m_reinsertFactor,
sizeof(
double));
904 ptr +=
sizeof(double);
905 memcpy(ptr, &m_dimension,
sizeof(uint32_t));
906 ptr +=
sizeof(uint32_t);
907 uint8_t c = (uint8_t) m_bTightMBRs;
908 memcpy(ptr, &c,
sizeof(uint8_t));
909 ptr +=
sizeof(uint8_t);
910 memcpy(ptr, &(m_stats.m_u32Nodes),
sizeof(uint32_t));
911 ptr +=
sizeof(uint32_t);
912 memcpy(ptr, &(m_stats.m_u64TotalData),
sizeof(uint64_t));
913 ptr +=
sizeof(uint64_t);
914 memcpy(ptr, &(m_stats.m_u32DeadIndexNodes),
sizeof(uint32_t));
915 ptr +=
sizeof(uint32_t);
916 memcpy(ptr, &(m_stats.m_u32DeadLeafNodes),
sizeof(uint32_t));
917 ptr +=
sizeof(uint32_t);
918 memcpy(ptr, &(m_stats.m_u64Data),
sizeof(uint64_t));
919 ptr +=
sizeof(uint64_t);
921 u32I =
static_cast<uint32_t
>(m_stats.m_treeHeight.size());
922 memcpy(ptr, &u32I,
sizeof(uint32_t));
923 ptr +=
sizeof(uint32_t);
925 for (
size_t cIndex = 0; cIndex < m_stats.m_treeHeight.size(); ++cIndex)
927 u32I = m_stats.m_treeHeight[cIndex];
928 memcpy(ptr, &u32I,
sizeof(uint32_t));
929 ptr +=
sizeof(uint32_t);
932 memcpy(ptr, &m_strongVersionOverflow,
sizeof(
double));
933 ptr +=
sizeof(double);
936 memcpy(ptr, &m_versionUnderflow,
sizeof(
double));
937 ptr +=
sizeof(double);
938 memcpy(ptr, &m_currentTime,
sizeof(
double));
939 ptr +=
sizeof(double);
941 u32I =
static_cast<uint32_t
>(m_stats.m_nodesInLevel.size());
942 memcpy(ptr, &u32I,
sizeof(uint32_t));
943 ptr +=
sizeof(uint32_t);
945 for (
size_t cLevel = 0; cLevel < m_stats.m_nodesInLevel.size(); ++cLevel)
947 u32I = m_stats.m_nodesInLevel[cLevel];
948 memcpy(ptr, &u32I,
sizeof(uint32_t));
949 ptr +=
sizeof(uint32_t);
952 m_pStorageManager->
storeByteArray(m_headerID, headerSize, header);
957 void SpatialIndex::MVRTree::MVRTree::loadHeader()
960 uint8_t* header =
nullptr;
961 m_pStorageManager->
loadByteArray(m_headerID, headerSize, &header);
963 uint8_t* ptr = header;
966 memcpy(&rootsSize, ptr,
sizeof(uint32_t));
967 ptr +=
sizeof(uint32_t);
969 for (uint32_t cIndex = 0; cIndex < rootsSize; ++cIndex)
972 memcpy(&(e.m_id), ptr,
sizeof(
id_type));
974 memcpy(&(e.m_startTime), ptr,
sizeof(
double));
975 ptr +=
sizeof(double);
976 memcpy(&(e.m_endTime), ptr,
sizeof(
double));
977 ptr +=
sizeof(double);
978 m_roots.push_back(e);
983 memcpy(&m_fillFactor, ptr,
sizeof(
double));
984 ptr +=
sizeof(double);
985 memcpy(&m_indexCapacity, ptr,
sizeof(uint32_t));
986 ptr +=
sizeof(uint32_t);
987 memcpy(&m_leafCapacity, ptr,
sizeof(uint32_t));
988 ptr +=
sizeof(uint32_t);
989 memcpy(&m_nearMinimumOverlapFactor, ptr,
sizeof(uint32_t));
990 ptr +=
sizeof(uint32_t);
991 memcpy(&m_splitDistributionFactor, ptr,
sizeof(
double));
992 ptr +=
sizeof(double);
993 memcpy(&m_reinsertFactor, ptr,
sizeof(
double));
994 ptr +=
sizeof(double);
995 memcpy(&m_dimension, ptr,
sizeof(uint32_t));
996 ptr +=
sizeof(uint32_t);
998 memcpy(&c, ptr,
sizeof(uint8_t));
999 m_bTightMBRs = (c != 0);
1000 ptr +=
sizeof(uint8_t);
1001 memcpy(&(m_stats.m_u32Nodes), ptr,
sizeof(uint32_t));
1002 ptr +=
sizeof(uint32_t);
1003 memcpy(&(m_stats.m_u64TotalData), ptr,
sizeof(uint64_t));
1004 ptr +=
sizeof(uint64_t);
1005 memcpy(&(m_stats.m_u32DeadIndexNodes), ptr,
sizeof(uint32_t));
1006 ptr +=
sizeof(uint32_t);
1007 memcpy(&(m_stats.m_u32DeadLeafNodes), ptr,
sizeof(uint32_t));
1008 ptr +=
sizeof(uint32_t);
1009 memcpy(&(m_stats.m_u64Data), ptr,
sizeof(uint64_t));
1010 ptr +=
sizeof(uint64_t);
1012 uint32_t treeHeightSize;
1013 memcpy(&treeHeightSize, ptr,
sizeof(uint32_t));
1014 ptr +=
sizeof(uint32_t);
1016 for (uint32_t cIndex = 0; cIndex < treeHeightSize; ++cIndex)
1019 memcpy(&u32I, ptr,
sizeof(uint32_t));
1020 m_stats.m_treeHeight.push_back(u32I);
1021 ptr +=
sizeof(uint32_t);
1024 memcpy(&m_strongVersionOverflow, ptr,
sizeof(
double));
1025 ptr +=
sizeof(double);
1028 memcpy(&m_versionUnderflow, ptr,
sizeof(
double));
1029 ptr +=
sizeof(double);
1030 memcpy(&m_currentTime, ptr,
sizeof(
double));
1031 ptr +=
sizeof(double);
1033 uint32_t nodesInLevelSize;
1034 memcpy(&nodesInLevelSize, ptr,
sizeof(uint32_t));
1035 ptr +=
sizeof(uint32_t);
1037 for (uint32_t cLevel = 0; cLevel < nodesInLevelSize; ++cLevel)
1040 memcpy(&u32I, ptr,
sizeof(uint32_t));
1041 ptr +=
sizeof(uint32_t);
1042 m_stats.m_nodesInLevel.push_back(u32I);
1048 void SpatialIndex::MVRTree::MVRTree::insertData_impl(uint32_t dataLength, uint8_t* pData,
TimeRegion& mbr,
id_type id)
1053 std::stack<id_type> pathBuffer;
1056 NodePtr root = readNode(m_roots[m_roots.size() - 1].m_id);
1057 NodePtr l = root->chooseSubtree(mbr, 0, pathBuffer);
1059 if (l.get() == root.
get())
1064 l->insertData(dataLength, pData, mbr,
id, pathBuffer, m_infiniteRegion, -1,
false);
1066 ++(m_stats.m_u64Data);
1067 ++(m_stats.m_u64TotalData);
1070 void SpatialIndex::MVRTree::MVRTree::insertData_impl(uint32_t dataLength, uint8_t* pData,
TimeRegion& mbr,
id_type id, uint32_t level)
1074 std::stack<id_type> pathBuffer;
1076 NodePtr root = readNode(m_roots[m_roots.size() - 1].m_id);
1077 NodePtr l = root->chooseSubtree(mbr, level, pathBuffer);
1079 assert(l->m_level == level);
1081 if (l.get() == root.
get())
1086 l->insertData(dataLength, pData, mbr,
id, pathBuffer, m_infiniteRegion, -1,
false);
1089 bool SpatialIndex::MVRTree::MVRTree::deleteData_impl(
const TimeRegion& mbr,
id_type id)
1095 std::stack<id_type> pathBuffer;
1096 NodePtr root = readNode(m_roots[m_roots.size() - 1].m_id);
1097 NodePtr l = root->findLeaf(mbr,
id, pathBuffer);
1099 if (l.get() == root.
get())
1105 if (l.get() !=
nullptr)
1107 l->deleteData(
id, mbr.
m_endTime, pathBuffer);
1108 --(m_stats.m_u64Data);
1118 uint32_t dataLength;
1123 else page = n->m_identifier;
1133 std::cerr << e.
what() << std::endl;
1138 if (n->m_identifier < 0)
1140 n->m_identifier = page;
1141 ++(m_stats.m_u32Nodes);
1144 ++(m_stats.m_u64Writes);
1146 for (
size_t cIndex = 0; cIndex < m_writeNodeCommands.size(); ++cIndex)
1148 m_writeNodeCommands[cIndex]->execute(*n);
1156 uint32_t dataLength;
1165 std::cerr << e.
what() << std::endl;
1173 memcpy(&nodeType, buffer,
sizeof(uint32_t));
1181 if (n.
get() ==
nullptr)
1188 n->m_identifier = id;
1191 ++(m_stats.m_u64Reads);
1193 for (
size_t cIndex = 0; cIndex < m_readNodeCommands.size(); ++cIndex)
1195 m_readNodeCommands[cIndex]->execute(*n);
1208 void SpatialIndex::MVRTree::MVRTree::deleteNode(
Node* n)
1216 std::cerr << e.
what() << std::endl;
1221 --(m_stats.m_u32Nodes);
1223 for (
size_t cIndex = 0; cIndex < m_deleteNodeCommands.size(); ++cIndex)
1225 m_deleteNodeCommands[cIndex]->execute(*n);
1237 std::set<id_type> visitedNodes;
1238 std::set<id_type> visitedData;
1239 std::stack<NodePtr> st;
1240 std::vector<id_type> ids;
1241 findRootIdentifiers(*ti, ids);
1243 for (
size_t cRoot = 0; cRoot < ids.size(); ++cRoot)
1245 NodePtr root = readNode(ids[cRoot]);
1246 if (root->m_children > 0 && query.
intersectsShape(root->m_nodeMBR)) st.push(root);
1249 while (! st.empty())
1251 NodePtr n = st.top(); st.pop();
1252 visitedNodes.insert(n->m_identifier);
1254 if (n->m_level == 0)
1258 for (uint32_t cChild = 0; cChild < n->m_children; ++cChild)
1260 if (visitedData.find(n->m_pIdentifier[cChild]) != visitedData.end())
continue;
1264 else b = (n->m_ptrMBR[cChild])->intersectsInterval(*ti) && query.
intersectsShape(*(n->m_ptrMBR[cChild]));
1268 visitedData.insert(n->m_pIdentifier[cChild]);
1269 Data data =
Data(n->m_pDataLength[cChild], n->m_pData[cChild], *(n->m_ptrMBR[cChild]), n->m_pIdentifier[cChild]);
1271 ++(m_stats.m_u64QueryResults);
1279 for (uint32_t cChild = 0; cChild < n->m_children; ++cChild)
1282 visitedNodes.find(n->m_pIdentifier[cChild]) == visitedNodes.end() &&
1285 st.push(readNode(n->m_pIdentifier[cChild]));
1291 void SpatialIndex::MVRTree::MVRTree::findRootIdentifiers(
const Tools::IInterval& ti, std::vector<id_type>& ids)
1295 for (
size_t cRoot = 0; cRoot < m_roots.size(); ++cRoot)
1297 RootEntry& e = m_roots[cRoot];
1302 std::string SpatialIndex::MVRTree::MVRTree::printRootInfo()
const 1304 std::ostringstream s;
1306 for (
size_t cRoot = 0; cRoot < m_roots.size(); ++cRoot)
1308 const RootEntry& e = m_roots[cRoot];
1310 s <<
"Root " << cRoot <<
": Start " << e.m_startTime <<
", End " << e.m_endTime << std::endl;
1318 os <<
"Dimension: " << t.m_dimension << std::endl
1319 <<
"Fill factor: " << t.m_fillFactor << std::endl
1320 <<
"Index capacity: " << t.m_indexCapacity << std::endl
1321 <<
"Leaf capacity: " << t.m_leafCapacity << std::endl
1322 <<
"Tight MBRs: " << ((t.m_bTightMBRs) ?
"enabled" :
"disabled") << std::endl;
1326 os <<
"Near minimum overlap factor: " << t.m_nearMinimumOverlapFactor << std::endl
1327 <<
"Reinsert factor: " << t.m_reinsertFactor << std::endl
1328 <<
"Split distribution factor: " << t.m_splitDistributionFactor << std::endl
1329 <<
"Strong version overflow: " << t.m_strongVersionOverflow << std::endl
1331 <<
"Weak version underflow: " << t.m_versionUnderflow << std::endl;
1338 os << t.printRootInfo();
1341 os <<
"Leaf pool hits: " << t.m_leafPool.
m_hits << std::endl
1342 <<
"Leaf pool misses: " << t.m_leafPool.
m_misses << std::endl
1343 <<
"Index pool hits: " << t.m_indexPool.
m_hits << std::endl
1344 <<
"Index pool misses: " << t.m_indexPool.
m_misses << std::endl
1345 <<
"Region pool hits: " << t.m_regionPool.
m_hits << std::endl
1346 <<
"Region pool misses: " << t.m_regionPool.
m_misses << std::endl
1347 <<
"Point pool hits: " << t.m_pointPool.m_hits << std::endl
1348 <<
"Point pool misses: " << t.m_pointPool.m_misses << std::endl;
virtual void selfJoinQuery(const IShape &s, IVisitor &v)
void storeToByteArray(uint8_t **data, uint32_t &len) override
std::ostream & operator<<(std::ostream &os, const MVRTree &t)
uint32_t getByteArraySize() override
virtual void deleteByteArray(const id_type id)=0
virtual bool deleteData(const IShape &shape, id_type id)
void storeToByteArray(uint8_t **data, uint32_t &len) override
void makeInfinite(uint32_t dimension) override
virtual void nearestNeighborQuery(uint32_t k, const IShape &query, IVisitor &v, INearestNeighborComparator &)
void loadFromByteArray(const uint8_t *data) override
void getData(uint32_t &len, uint8_t **data) const override
virtual void storeByteArray(id_type &id, const uint32_t len, const uint8_t *const data)=0
virtual void queryStrategy(IQueryStrategy &qs)
bool intersectsInterval(const Tools::IInterval &ti) const override
void loadFromByteArray(const uint8_t *data) override
id_type getIdentifier() const override
virtual void loadByteArray(const id_type id, uint32_t &len, uint8_t **data)=0
virtual uint32_t getDimension() const =0
Tools::PoolPointer< Node > NodePtr
virtual void visitNode(const INode &in)=0
virtual void getIndexProperties(Tools::PropertySet &out) const
SIDX_DLL ISpatialIndex * createNewMVRTree(IStorageManager &in, double fillFactor, uint32_t indexCapacity, uint32_t leafCapacity, uint32_t dimension, MVRTreeVariant rv, id_type &out_indexIdentifier)
virtual bool intersectsShape(const IShape &in) const =0
virtual void containsWhatQuery(const IShape &query, IVisitor &v)
virtual void visitData(const IData &in)=0
virtual void pointLocationQuery(const Point &query, IVisitor &v)
uint32_t getDimension() const override
uint32_t getByteArraySize() override
SIDX_DLL ISpatialIndex * loadMVRTree(IStorageManager &in, id_type indexIdentifier)
virtual void insertData(uint32_t len, const uint8_t *pData, const IShape &shape, id_type id)
SIDX_DLL ISpatialIndex * returnMVRTree(IStorageManager &ind, Tools::PropertySet &in)
virtual void getMBR(Region &out) const =0
virtual void internalNodesQuery(const IShape &query, IVisitor &v)
void makeDimension(uint32_t dimension) override
virtual void getNextEntry(const IEntry &previouslyFetched, id_type &nextEntryToFetch, bool &bFetchNextEntry)=0
virtual bool containsShape(const IShape &in) const =0
void storeToByteArray(uint8_t **data, uint32_t &len) override
MVRTree(IStorageManager &, Tools::PropertySet &)
virtual bool isIndexValid()
virtual void intersectsWithQuery(const IShape &query, IVisitor &v)
void loadFromByteArray(const uint8_t *data) override
std::string what() override
virtual void getStatistics(IStatistics **out) const
virtual void addCommand(ICommand *pCommand, CommandType ct)
Data(uint32_t len, uint8_t *pData, TimeRegion &r, id_type id)
void getShape(IShape **out) const override