libspatialindex API Reference  (git-trunk)
tprtree/Leaf.cc
Go to the documentation of this file.
1 /******************************************************************************
2  * Project: libspatialindex - A C++ library for spatial indexing
3  * Author: Marios Hadjieleftheriou, mhadji@gmail.com
4  ******************************************************************************
5  * Copyright (c) 2002, Marios Hadjieleftheriou
6  *
7  * All rights reserved.
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining a
10  * copy of this software and associated documentation files (the "Software"),
11  * to deal in the Software without restriction, including without limitation
12  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13  * and/or sell copies of the Software, and to permit persons to whom the
14  * Software is furnished to do so, subject to the following conditions:
15  *
16  * The above copyright notice and this permission notice shall be included
17  * in all copies or substantial portions of the Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25  * DEALINGS IN THE SOFTWARE.
26 ******************************************************************************/
27 
28 #include <cstring>
29 
31 
32 #include "TPRTree.h"
33 #include "Node.h"
34 #include "Index.h"
35 #include "Leaf.h"
36 
37 using namespace SpatialIndex;
38 using namespace SpatialIndex::TPRTree;
39 
41 = default;
42 
44  : Node(pTree, id, 0, pTree->m_leafCapacity)
45 {
46 }
47 
48 NodePtr Leaf::chooseSubtree(const MovingRegion&, uint32_t, std::stack<id_type>&)
49 {
50  // should make sure to relinquish other PoolPointer lists that might be pointing to the
51  // same leaf.
52  return NodePtr(this, &(m_pTree->m_leafPool));
53 }
54 
55 NodePtr Leaf::findLeaf(const MovingRegion&, id_type id, std::stack<id_type>&)
56 {
57  for (uint32_t cChild = 0; cChild < m_children; ++cChild)
58  {
59  // should make sure to relinquish other PoolPointer lists that might be pointing to the
60  // same leaf.
61  if (m_pIdentifier[cChild] == id /*&& mbr == *(m_ptrMBR[cChild])*/) return NodePtr(this, &(m_pTree->m_leafPool));
62  }
63 
64  return NodePtr();
65 }
66 
67 void Leaf::split(uint32_t dataLength, uint8_t* pData, MovingRegion& mbr, id_type id, NodePtr& pLeft, NodePtr& pRight)
68 {
69  ++(m_pTree->m_stats.m_splits);
70 
71  std::vector<uint32_t> g1, g2;
72 
73  switch (m_pTree->m_treeVariant)
74  {
75  case TPRV_RSTAR:
76  rstarSplit(dataLength, pData, mbr, id, g1, g2);
77  break;
78  default:
79  throw Tools::NotSupportedException("Leaf::split: Tree variant not supported.");
80  }
81 
82  pLeft = m_pTree->m_leafPool.acquire();
83  pRight = m_pTree->m_leafPool.acquire();
84 
85  if (pLeft.get() == nullptr) pLeft = NodePtr(new Leaf(m_pTree, -1), &(m_pTree->m_leafPool));
86  if (pRight.get() == nullptr) pRight = NodePtr(new Leaf(m_pTree, -1), &(m_pTree->m_leafPool));
87 
88  pLeft->m_nodeMBR = m_pTree->m_infiniteRegion;
89  pRight->m_nodeMBR = m_pTree->m_infiniteRegion;
90 
91  uint32_t cIndex;
92 
93  for (cIndex = 0; cIndex < g1.size(); ++cIndex)
94  {
95  pLeft->insertEntry(m_pDataLength[g1[cIndex]], m_pData[g1[cIndex]], *(m_ptrMBR[g1[cIndex]]), m_pIdentifier[g1[cIndex]]);
96  // we don't want to delete the data array from this node's destructor!
97  m_pData[g1[cIndex]] = nullptr;
98  }
99 
100  for (cIndex = 0; cIndex < g2.size(); ++cIndex)
101  {
102  pRight->insertEntry(m_pDataLength[g2[cIndex]], m_pData[g2[cIndex]], *(m_ptrMBR[g2[cIndex]]), m_pIdentifier[g2[cIndex]]);
103  // we don't want to delete the data array from this node's destructor!
104  m_pData[g2[cIndex]] = nullptr;
105  }
106 }
107 
108 void Leaf::deleteData(id_type id, std::stack<id_type>& pathBuffer)
109 {
110  uint32_t child;
111 
112  for (child = 0; child < m_children; ++child)
113  {
114  if (m_pIdentifier[child] == id) break;
115  }
116 
117  deleteEntry(child);
118  m_pTree->writeNode(this);
119 
120  std::stack<NodePtr> toReinsert;
121  NodePtr ptrThis(this, &(m_pTree->m_leafPool));
122  condenseTree(toReinsert, pathBuffer, ptrThis);
123  ptrThis.relinquish();
124 
125  // re-insert eliminated nodes.
126  while (! toReinsert.empty())
127  {
128  NodePtr n = toReinsert.top(); toReinsert.pop();
129  m_pTree->deleteNode(n.get());
130 
131  for (uint32_t cChild = 0; cChild < n->m_children; ++cChild)
132  {
133  // keep this in the for loop. The tree height might change after insertions.
134  uint8_t* overflowTable = new uint8_t[m_pTree->m_stats.m_treeHeight];
135  memset(overflowTable, 0, m_pTree->m_stats.m_treeHeight);
136  m_pTree->insertData_impl(n->m_pDataLength[cChild], n->m_pData[cChild], *(n->m_ptrMBR[cChild]), n->m_pIdentifier[cChild], n->m_level, overflowTable);
137  n->m_pData[cChild] = nullptr;
138  delete[] overflowTable;
139  }
140  if (n.get() == this) n.relinquish();
141  }
142 }
X * get() const noexcept
Definition: PoolPointer.h:55
void relinquish() noexcept
Definition: PoolPointer.h:57
Tools::PoolPointer< Node > NodePtr
Definition: tprtree/Node.h:39
int64_t id_type
Definition: SpatialIndex.h:41