40 #define SI_DEBUG_OUTPUT 0
45 : m_id(id), m_region(r), m_pData(nullptr), m_dataLength(len)
61 return new Data(m_dataLength, m_pData, m_region, m_id);
81 *data =
new uint8_t[m_dataLength];
82 memcpy(*data, m_pData, m_dataLength);
92 m_region.getByteArraySize();
97 memcpy(&m_id, ptr,
sizeof(
id_type));
103 memcpy(&m_dataLength, ptr,
sizeof(uint32_t));
104 ptr +=
sizeof(uint32_t);
106 if (m_dataLength > 0)
108 m_pData =
new uint8_t[m_dataLength];
109 memcpy(m_pData, ptr, m_dataLength);
113 m_region.loadFromByteArray(ptr);
120 uint8_t* regiondata =
nullptr;
121 m_region.storeToByteArray(®iondata, regionsize);
123 len =
sizeof(
id_type) +
sizeof(uint32_t) + m_dataLength + regionsize;
125 *data =
new uint8_t[len];
126 uint8_t* ptr = *data;
128 memcpy(ptr, &m_id,
sizeof(
id_type));
130 memcpy(ptr, &m_dataLength,
sizeof(uint32_t));
131 ptr +=
sizeof(uint32_t);
133 if (m_dataLength > 0)
135 memcpy(ptr, m_pData, m_dataLength);
139 memcpy(ptr, regiondata, regionsize);
153 uint32_t indexCapacity,
154 uint32_t leafCapacity,
204 m_pStorageManager(&sm),
205 m_headerID(StorageManager::
NewPage),
208 m_indexCapacity(100),
210 m_nearMinimumOverlapFactor(32),
211 m_splitDistributionFactor(0.4),
212 m_reinsertFactor(0.3),
213 m_strongVersionOverflow(0.8),
215 m_versionUnderflow(0.3),
218 m_bHasVersionCopied(false),
271 mbr->
m_endTime = std::numeric_limits<double>::max();
273 uint8_t* buffer =
nullptr;
277 buffer =
new uint8_t[len];
278 memcpy(buffer, pData, len);
281 insertData_impl(len, buffer, *mbr,
id);
302 bool ret = deleteData_impl(*mbr,
id);
343 return nearestNeighborQuery(k, query, v, nnc, max_dist);
353 id_type next = m_roots[m_roots.size() - 1].m_id;
457 m_readNodeCommands.push_back(std::shared_ptr<ICommand>(pCommand));
460 m_writeNodeCommands.push_back(std::shared_ptr<ICommand>(pCommand));
463 m_deleteNodeCommands.push_back(std::shared_ptr<ICommand>(pCommand));
471 std::stack<ValidateEntry> st;
472 std::set<id_type> visitedEntries;
474 uint32_t degenerateEntries = 0;
477 for (uint32_t cRoot = 0; cRoot < m_roots.size(); ++cRoot)
479 NodePtr root = readNode(m_roots[cRoot].m_id);
481 if (root->m_level != m_stats.m_treeHeight[cRoot] - 1)
483 std::cerr <<
"Invalid tree height." << std::endl;
487 ValidateEntry e(0, root->m_nodeMBR, root);
488 e.m_bIsDead = (root->m_nodeMBR.
m_endTime < std::numeric_limits<double>::max()) ?
true :
false;
494 ValidateEntry e = st.top(); st.pop();
496 std::set<id_type>::iterator itSet = visitedEntries.find(e.m_pNode->m_identifier);
497 if (itSet == visitedEntries.end())
499 visitedEntries.insert(e.m_pNode->m_identifier);
501 if (e.m_pNode->m_nodeMBR.m_startTime == e.m_pNode->m_nodeMBR.m_endTime) ++degenerateEntries;
506 tmpRegion = m_infiniteRegion;
508 for (uint32_t cDim = 0; cDim < tmpRegion.
m_dimension; ++cDim)
510 for (uint32_t cChild = 0; cChild < e.m_pNode->m_children; ++cChild)
512 tmpRegion.
m_pLow[cDim] = std::min(tmpRegion.
m_pLow[cDim], e.m_pNode->m_ptrMBR[cChild]->m_pLow[cDim]);
513 tmpRegion.
m_pHigh[cDim] = std::max(tmpRegion.
m_pHigh[cDim], e.m_pNode->m_ptrMBR[cChild]->m_pHigh[cDim]);
517 tmpRegion.
m_startTime = e.m_pNode->m_nodeMBR.m_startTime;
518 tmpRegion.
m_endTime = e.m_pNode->m_nodeMBR.m_endTime;
519 if (! (tmpRegion == e.m_pNode->m_nodeMBR))
521 std::cerr <<
"Invalid parent information." << std::endl;
528 tmpRegion.
m_endTime = e.m_parentMBR.m_endTime;
529 if (! (tmpRegion == e.m_parentMBR))
531 std::cerr <<
"Error in parent (Node id: " << e.m_pNode->m_identifier <<
", Parent id: " << e.m_parentID <<
")." << std::endl;
536 if (e.m_pNode->m_level != 0)
538 for (uint32_t cChild = 0; cChild < e.m_pNode->m_children; ++cChild)
540 NodePtr ptrN = readNode(e.m_pNode->m_pIdentifier[cChild]);
543 (e.m_pNode->m_ptrMBR[cChild]->m_endTime < std::numeric_limits<double>::max() || e.m_bIsDead) ?
true :
false;
547 if (bIsDead) ptrN->m_nodeMBR.
m_endTime = e.m_pNode->m_ptrMBR[cChild]->m_endTime;
549 ValidateEntry tmpEntry(e.m_pNode->m_identifier, *(e.m_pNode->m_ptrMBR[cChild]), ptrN);
550 tmpEntry.m_bIsDead = bIsDead;
557 std::cerr <<
"Total accessible nodes: " << visitedEntries.size() << std::endl;
558 std::cerr <<
"Degenerate nodes: " << degenerateEntries << std::endl;
599 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");
629 throw Tools::IllegalArgumentException(
"initNew: Property NearMinimumOverlapFactor must be Tools::VT_ULONG and less than both index and leaf capacities");
740 m_infiniteRegion.makeInfinite(m_dimension);
742 m_stats.m_treeHeight.push_back(1);
743 m_stats.m_nodesInLevel.push_back(1);
746 root.m_nodeMBR.m_startTime = 0.0;
747 root.m_nodeMBR.m_endTime = std::numeric_limits<double>::max();
749 m_roots.emplace_back(root.m_identifier, root.m_nodeMBR.m_startTime, root.m_nodeMBR.m_endTime);
778 throw Tools::IllegalArgumentException(
"initOld: Property NearMinimumOverlapFactor must be Tools::VT_ULONG and less than both index and leaf capacities");
848 m_infiniteRegion.makeInfinite(m_dimension);
851 void SpatialIndex::MVRTree::MVRTree::storeHeader()
853 const uint32_t headerSize =
855 static_cast<uint32_t
>(m_roots.size())
856 * (
sizeof(
id_type) + 2 *
sizeof(double)) +
872 static_cast<uint32_t
>(m_stats.m_treeHeight.size())
879 static_cast<uint32_t
>(m_stats.m_nodesInLevel.size())
882 uint8_t* header =
new uint8_t[headerSize];
883 uint8_t* ptr = header;
885 uint32_t u32I =
static_cast<uint32_t
>(m_roots.size());
886 memcpy(ptr, &u32I,
sizeof(uint32_t));
887 ptr +=
sizeof(uint32_t);
889 for (
size_t cIndex = 0; cIndex < m_roots.size(); ++cIndex)
891 RootEntry& e = m_roots[cIndex];
892 memcpy(ptr, &(e.m_id),
sizeof(
id_type));
894 memcpy(ptr, &(e.m_startTime),
sizeof(
double));
895 ptr +=
sizeof(double);
896 memcpy(ptr, &(e.m_endTime),
sizeof(
double));
897 ptr +=
sizeof(double);
902 memcpy(ptr, &m_fillFactor,
sizeof(
double));
903 ptr +=
sizeof(double);
904 memcpy(ptr, &m_indexCapacity,
sizeof(uint32_t));
905 ptr +=
sizeof(uint32_t);
906 memcpy(ptr, &m_leafCapacity,
sizeof(uint32_t));
907 ptr +=
sizeof(uint32_t);
908 memcpy(ptr, &m_nearMinimumOverlapFactor,
sizeof(uint32_t));
909 ptr +=
sizeof(uint32_t);
910 memcpy(ptr, &m_splitDistributionFactor,
sizeof(
double));
911 ptr +=
sizeof(double);
912 memcpy(ptr, &m_reinsertFactor,
sizeof(
double));
913 ptr +=
sizeof(double);
914 memcpy(ptr, &m_dimension,
sizeof(uint32_t));
915 ptr +=
sizeof(uint32_t);
916 uint8_t c = (uint8_t) m_bTightMBRs;
917 memcpy(ptr, &c,
sizeof(uint8_t));
918 ptr +=
sizeof(uint8_t);
919 memcpy(ptr, &(m_stats.m_u32Nodes),
sizeof(uint32_t));
920 ptr +=
sizeof(uint32_t);
921 memcpy(ptr, &(m_stats.m_u64TotalData),
sizeof(uint64_t));
922 ptr +=
sizeof(uint64_t);
923 memcpy(ptr, &(m_stats.m_u32DeadIndexNodes),
sizeof(uint32_t));
924 ptr +=
sizeof(uint32_t);
925 memcpy(ptr, &(m_stats.m_u32DeadLeafNodes),
sizeof(uint32_t));
926 ptr +=
sizeof(uint32_t);
927 memcpy(ptr, &(m_stats.m_u64Data),
sizeof(uint64_t));
928 ptr +=
sizeof(uint64_t);
930 u32I =
static_cast<uint32_t
>(m_stats.m_treeHeight.size());
931 memcpy(ptr, &u32I,
sizeof(uint32_t));
932 ptr +=
sizeof(uint32_t);
934 for (
size_t cIndex = 0; cIndex < m_stats.m_treeHeight.size(); ++cIndex)
936 u32I = m_stats.m_treeHeight[cIndex];
937 memcpy(ptr, &u32I,
sizeof(uint32_t));
938 ptr +=
sizeof(uint32_t);
941 memcpy(ptr, &m_strongVersionOverflow,
sizeof(
double));
942 ptr +=
sizeof(double);
945 memcpy(ptr, &m_versionUnderflow,
sizeof(
double));
946 ptr +=
sizeof(double);
947 memcpy(ptr, &m_currentTime,
sizeof(
double));
948 ptr +=
sizeof(double);
950 u32I =
static_cast<uint32_t
>(m_stats.m_nodesInLevel.size());
951 memcpy(ptr, &u32I,
sizeof(uint32_t));
952 ptr +=
sizeof(uint32_t);
954 for (
size_t cLevel = 0; cLevel < m_stats.m_nodesInLevel.size(); ++cLevel)
956 u32I = m_stats.m_nodesInLevel[cLevel];
957 memcpy(ptr, &u32I,
sizeof(uint32_t));
958 ptr +=
sizeof(uint32_t);
961 m_pStorageManager->storeByteArray(m_headerID, headerSize, header);
966 void SpatialIndex::MVRTree::MVRTree::loadHeader()
969 uint8_t* header =
nullptr;
970 m_pStorageManager->loadByteArray(m_headerID, headerSize, &header);
972 uint8_t* ptr = header;
975 memcpy(&rootsSize, ptr,
sizeof(uint32_t));
976 ptr +=
sizeof(uint32_t);
978 for (uint32_t cIndex = 0; cIndex < rootsSize; ++cIndex)
981 memcpy(&(e.m_id), ptr,
sizeof(
id_type));
983 memcpy(&(e.m_startTime), ptr,
sizeof(
double));
984 ptr +=
sizeof(double);
985 memcpy(&(e.m_endTime), ptr,
sizeof(
double));
986 ptr +=
sizeof(double);
987 m_roots.push_back(e);
992 memcpy(&m_fillFactor, ptr,
sizeof(
double));
993 ptr +=
sizeof(double);
994 memcpy(&m_indexCapacity, ptr,
sizeof(uint32_t));
995 ptr +=
sizeof(uint32_t);
996 memcpy(&m_leafCapacity, ptr,
sizeof(uint32_t));
997 ptr +=
sizeof(uint32_t);
998 memcpy(&m_nearMinimumOverlapFactor, ptr,
sizeof(uint32_t));
999 ptr +=
sizeof(uint32_t);
1000 memcpy(&m_splitDistributionFactor, ptr,
sizeof(
double));
1001 ptr +=
sizeof(double);
1002 memcpy(&m_reinsertFactor, ptr,
sizeof(
double));
1003 ptr +=
sizeof(double);
1004 memcpy(&m_dimension, ptr,
sizeof(uint32_t));
1005 ptr +=
sizeof(uint32_t);
1007 memcpy(&c, ptr,
sizeof(uint8_t));
1008 m_bTightMBRs = (c != 0);
1009 ptr +=
sizeof(uint8_t);
1010 memcpy(&(m_stats.m_u32Nodes), ptr,
sizeof(uint32_t));
1011 ptr +=
sizeof(uint32_t);
1012 memcpy(&(m_stats.m_u64TotalData), ptr,
sizeof(uint64_t));
1013 ptr +=
sizeof(uint64_t);
1014 memcpy(&(m_stats.m_u32DeadIndexNodes), ptr,
sizeof(uint32_t));
1015 ptr +=
sizeof(uint32_t);
1016 memcpy(&(m_stats.m_u32DeadLeafNodes), ptr,
sizeof(uint32_t));
1017 ptr +=
sizeof(uint32_t);
1018 memcpy(&(m_stats.m_u64Data), ptr,
sizeof(uint64_t));
1019 ptr +=
sizeof(uint64_t);
1021 uint32_t treeHeightSize;
1022 memcpy(&treeHeightSize, ptr,
sizeof(uint32_t));
1023 ptr +=
sizeof(uint32_t);
1025 for (uint32_t cIndex = 0; cIndex < treeHeightSize; ++cIndex)
1028 memcpy(&u32I, ptr,
sizeof(uint32_t));
1029 m_stats.m_treeHeight.push_back(u32I);
1030 ptr +=
sizeof(uint32_t);
1033 memcpy(&m_strongVersionOverflow, ptr,
sizeof(
double));
1034 ptr +=
sizeof(double);
1037 memcpy(&m_versionUnderflow, ptr,
sizeof(
double));
1038 ptr +=
sizeof(double);
1039 memcpy(&m_currentTime, ptr,
sizeof(
double));
1040 ptr +=
sizeof(double);
1042 uint32_t nodesInLevelSize;
1043 memcpy(&nodesInLevelSize, ptr,
sizeof(uint32_t));
1044 ptr +=
sizeof(uint32_t);
1046 for (uint32_t cLevel = 0; cLevel < nodesInLevelSize; ++cLevel)
1049 memcpy(&u32I, ptr,
sizeof(uint32_t));
1050 ptr +=
sizeof(uint32_t);
1051 m_stats.m_nodesInLevel.push_back(u32I);
1057 void SpatialIndex::MVRTree::MVRTree::insertData_impl(uint32_t dataLength, uint8_t* pData, TimeRegion& mbr,
id_type id)
1059 assert(mbr.getDimension() == m_dimension);
1060 assert(m_currentTime <= mbr.m_startTime);
1062 std::stack<id_type> pathBuffer;
1063 m_currentTime = mbr.m_startTime;
1065 NodePtr root = readNode(m_roots[m_roots.size() - 1].m_id);
1066 NodePtr l = root->chooseSubtree(mbr, 0, pathBuffer);
1068 if (l.
get() == root.
get())
1073 l->insertData(dataLength, pData, mbr,
id, pathBuffer, m_infiniteRegion, -1,
false);
1075 ++(m_stats.m_u64Data);
1076 ++(m_stats.m_u64TotalData);
1079 void SpatialIndex::MVRTree::MVRTree::insertData_impl(uint32_t dataLength, uint8_t* pData, TimeRegion& mbr,
id_type id, uint32_t level)
1081 assert(mbr.getDimension() == m_dimension);
1083 std::stack<id_type> pathBuffer;
1085 NodePtr root = readNode(m_roots[m_roots.size() - 1].m_id);
1086 NodePtr l = root->chooseSubtree(mbr, level, pathBuffer);
1088 assert(l->m_level == level);
1090 if (l.
get() == root.
get())
1095 l->insertData(dataLength, pData, mbr,
id, pathBuffer, m_infiniteRegion, -1,
false);
1098 bool SpatialIndex::MVRTree::MVRTree::deleteData_impl(
const TimeRegion& mbr,
id_type id)
1100 assert(mbr.m_dimension == m_dimension);
1102 m_currentTime = mbr.m_endTime;
1104 std::stack<id_type> pathBuffer;
1105 NodePtr root = readNode(m_roots[m_roots.size() - 1].m_id);
1106 NodePtr l = root->findLeaf(mbr,
id, pathBuffer);
1108 if (l.
get() == root.
get())
1114 if (l.
get() !=
nullptr)
1116 l->deleteData(
id, mbr.m_endTime, pathBuffer);
1117 --(m_stats.m_u64Data);
1127 uint32_t dataLength;
1132 else page = n->m_identifier;
1136 m_pStorageManager->storeByteArray(page, dataLength, buffer);
1139 catch (InvalidPageException& e)
1142 std::cerr << e.what() << std::endl;
1147 if (n->m_identifier < 0)
1149 n->m_identifier = page;
1150 ++(m_stats.m_u32Nodes);
1153 ++(m_stats.m_u64Writes);
1155 for (
size_t cIndex = 0; cIndex < m_writeNodeCommands.size(); ++cIndex)
1157 m_writeNodeCommands[cIndex]->execute(*n);
1165 uint32_t dataLength;
1170 m_pStorageManager->loadByteArray(
id, dataLength, &buffer);
1172 catch (InvalidPageException& e)
1174 std::cerr << e.what() << std::endl;
1182 memcpy(&nodeType, buffer,
sizeof(uint32_t));
1190 if (n.
get() ==
nullptr)
1197 n->m_identifier = id;
1200 ++(m_stats.m_u64Reads);
1202 for (
size_t cIndex = 0; cIndex < m_readNodeCommands.size(); ++cIndex)
1204 m_readNodeCommands[cIndex]->execute(*n);
1217 void SpatialIndex::MVRTree::MVRTree::deleteNode(
Node* n)
1221 m_pStorageManager->deleteByteArray(n->m_identifier);
1223 catch (InvalidPageException& e)
1225 std::cerr << e.what() << std::endl;
1230 --(m_stats.m_u32Nodes);
1232 for (
size_t cIndex = 0; cIndex < m_deleteNodeCommands.size(); ++cIndex)
1234 m_deleteNodeCommands[cIndex]->execute(*n);
1238 void SpatialIndex::MVRTree::MVRTree::rangeQuery(
RangeQueryType type,
const IShape& query, IVisitor& v)
1246 std::set<id_type> visitedNodes;
1247 std::set<id_type> visitedData;
1248 std::stack<NodePtr> st;
1249 std::vector<id_type> ids;
1250 findRootIdentifiers(*ti, ids);
1252 for (
size_t cRoot = 0; cRoot < ids.size(); ++cRoot)
1254 NodePtr root = readNode(ids[cRoot]);
1255 if (root->m_children > 0 && query.intersectsShape(root->m_nodeMBR)) st.push(root);
1258 while (! st.empty())
1260 NodePtr n = st.top(); st.pop();
1261 visitedNodes.insert(n->m_identifier);
1263 if (n->m_level == 0)
1267 for (uint32_t cChild = 0; cChild < n->m_children; ++cChild)
1269 if (visitedData.find(n->m_pIdentifier[cChild]) != visitedData.end())
continue;
1272 if (type ==
ContainmentQuery) b = (n->m_ptrMBR[cChild])->intersectsInterval(*ti) && query.containsShape(*(n->m_ptrMBR[cChild]));
1273 else b = (n->m_ptrMBR[cChild])->intersectsInterval(*ti) && query.intersectsShape(*(n->m_ptrMBR[cChild]));
1277 visitedData.insert(n->m_pIdentifier[cChild]);
1278 Data data =
Data(n->m_pDataLength[cChild], n->m_pData[cChild], *(n->m_ptrMBR[cChild]), n->m_pIdentifier[cChild]);
1280 ++(m_stats.m_u64QueryResults);
1288 for (uint32_t cChild = 0; cChild < n->m_children; ++cChild)
1291 visitedNodes.find(n->m_pIdentifier[cChild]) == visitedNodes.end() &&
1293 query.intersectsShape(*(n->m_ptrMBR[cChild])))
1294 st.push(readNode(n->m_pIdentifier[cChild]));
1300 void SpatialIndex::MVRTree::MVRTree::findRootIdentifiers(
const Tools::IInterval& ti, std::vector<id_type>& ids)
1304 for (
size_t cRoot = 0; cRoot < m_roots.size(); ++cRoot)
1306 RootEntry& e = m_roots[cRoot];
1311 std::string SpatialIndex::MVRTree::MVRTree::printRootInfo()
const
1313 std::ostringstream s;
1315 for (
size_t cRoot = 0; cRoot < m_roots.size(); ++cRoot)
1317 const RootEntry& e = m_roots[cRoot];
1319 s <<
"Root " << cRoot <<
": Start " << e.m_startTime <<
", End " << e.m_endTime << std::endl;
1327 os <<
"Dimension: " << t.m_dimension << std::endl
1328 <<
"Fill factor: " << t.m_fillFactor << std::endl
1329 <<
"Index capacity: " << t.m_indexCapacity << std::endl
1330 <<
"Leaf capacity: " << t.m_leafCapacity << std::endl
1331 <<
"Tight MBRs: " << ((t.m_bTightMBRs) ?
"enabled" :
"disabled") << std::endl;
1335 os <<
"Near minimum overlap factor: " << t.m_nearMinimumOverlapFactor << std::endl
1336 <<
"Reinsert factor: " << t.m_reinsertFactor << std::endl
1337 <<
"Split distribution factor: " << t.m_splitDistributionFactor << std::endl
1338 <<
"Strong version overflow: " << t.m_strongVersionOverflow << std::endl
1340 <<
"Weak version underflow: " << t.m_versionUnderflow << std::endl;
1347 os << t.printRootInfo();
virtual void getNextEntry(const IEntry &previouslyFetched, id_type &nextEntryToFetch, bool &bFetchNextEntry)=0
virtual uint32_t getDimension() const =0
virtual void getMBR(Region &out) const =0
void getShape(IShape **out) const override
void getData(uint32_t &len, uint8_t **data) const override
id_type getIdentifier() const override
Data(uint32_t len, uint8_t *pData, TimeRegion &r, id_type id)
uint32_t getByteArraySize() override
void loadFromByteArray(const uint8_t *data) override
void storeToByteArray(uint8_t **data, uint32_t &len) override
virtual void pointLocationQuery(const Point &query, IVisitor &v)
virtual void addCommand(ICommand *pCommand, CommandType ct)
virtual void getIndexProperties(Tools::PropertySet &out) const
virtual void queryStrategy(IQueryStrategy &qs)
virtual void internalNodesQuery(const IShape &query, IVisitor &v)
virtual double nearestNeighborQuery(uint32_t k, const IShape &query, IVisitor &v, INearestNeighborComparator &, double max_dist=0.0)
virtual void getStatistics(IStatistics **out) const
virtual void containsWhatQuery(const IShape &query, IVisitor &v)
virtual void selfJoinQuery(const IShape &s, IVisitor &v)
virtual bool deleteData(const IShape &shape, id_type id)
MVRTree(IStorageManager &, Tools::PropertySet &)
virtual void insertData(uint32_t len, const uint8_t *pData, const IShape &shape, id_type id)
virtual void intersectsWithQuery(const IShape &query, IVisitor &v)
virtual bool isIndexValid()
void loadFromByteArray(const uint8_t *data) override
void storeToByteArray(uint8_t **data, uint32_t &len) override
void makeDimension(uint32_t dimension) override
bool intersectsInterval(const Tools::IInterval &ti) const override
SIDX_DLL ISpatialIndex * createNewMVRTree(IStorageManager &in, double fillFactor, uint32_t indexCapacity, uint32_t leafCapacity, uint32_t dimension, MVRTreeVariant rv, id_type &out_indexIdentifier)
SIDX_DLL ISpatialIndex * returnMVRTree(IStorageManager &ind, Tools::PropertySet &in)
Tools::PoolPointer< Node > NodePtr
SIDX_DLL ISpatialIndex * loadMVRTree(IStorageManager &in, id_type indexIdentifier)
std::ostream & operator<<(std::ostream &os, const MVRTree &t)