00001
00002
00003 #ifndef VGS_RTree_H
00004 #define VGS_RTree_H
00005
00006 #include <assert.h>
00007
00008 #include <vector>
00009 #include <stack>
00010 #include <queue>
00011 #include <algorithm>
00012 #include <limits>
00013 #include <fstream>
00014 #include <iostream>
00015 #include <ostream>
00016
00017 #include "GraphTypes.h"
00018
00019 namespace VGServer {
00020
00021
00022
00023 #define R_STAR_TREE
00024
00028
00029 class RTree
00030 {
00031 public:
00032
00033
00034
00035 typedef coord_t CoordType;
00036 typedef long long AreaType;
00037
00038
00039
00040
00041 class Point;
00042 class Rect;
00043
00045 class Point
00046 {
00047 public:
00048 CoordType x, y;
00049
00051 inline Point()
00052 { }
00053
00055 inline Point(CoordType _x, CoordType _y)
00056 : x(_x), y(_y)
00057 { }
00058
00060 static inline AreaType square(AreaType a)
00061 { return a * a; }
00062
00064 inline AreaType getDistanceSquare(const Point &p) const
00065 {
00066 return square( p.x - x )
00067 + square( p.y - y );
00068 }
00069
00071 inline AreaType getDistanceSquare(CoordType px, CoordType py) const
00072 {
00073 return square( px - x )
00074 + square( py - y );
00075 }
00076
00078 inline AreaType getMinimumDistanceSquare(const class Rect &r) const
00079 {
00080 AreaType a = 0;
00081
00082 if (x < r.x1 || r.x2 < x)
00083 a += square( std::min(x - r.x1, x - r.x2) );
00084
00085 if (y < r.y1 || r.y2 < y)
00086 a += square( std::min(y - r.y1, y - r.y2) );
00087
00088 return a;
00089 }
00090
00092 inline AreaType getDistanceLineSquare(CoordType x1, CoordType y1, CoordType x2, CoordType y2) const
00093 {
00094
00095
00096 double l = square(x1 - x2) + square(y1 - y2);
00097
00098
00099 double r = static_cast<double>((x - x1) * (x2 - x1) + (y - y1) * (y2 - y1)) / l;
00100
00101 if (r <= 0)
00102 {
00103
00104 return square(x1 - x) + square(y1 - y);
00105 }
00106 else if (r >= 1)
00107 {
00108
00109 return square(x2 - x) + square(y2 - y);
00110 }
00111 else
00112 {
00113
00114 double s = static_cast<double>(square( (y1 - y) * (x2 - x1) - (x1 - x) * (y2 - y1) )) / l;
00115
00116 return static_cast<AreaType>(s);
00117 }
00118 }
00119 };
00120
00122 class Rect
00123 {
00124 public:
00125 CoordType x1, y1, x2, y2;
00126
00128 inline Rect()
00129 { }
00130
00132 inline Rect(CoordType _x1, CoordType _y1, CoordType _x2, CoordType _y2)
00133 : x1(_x1), y1(_y1), x2(_x2), y2(_y2)
00134 {
00135 assert(x1 <= x2);
00136 assert(y1 <= y2);
00137 }
00138
00140 inline bool valid() const
00141 {
00142 return (x1 <= x2) && (y1 <= y2);
00143 }
00144
00146 inline bool operator==(const Rect &o) const
00147 {
00148 return (x1 == o.x1) && (y1 == o.y1) && (x2 == o.x2) && (y2 == o.y2);
00149 }
00150
00153 inline void setInfinite()
00154 {
00155 x1 = y1 = std::numeric_limits<CoordType>::max();
00156 x2 = y2 = std::numeric_limits<CoordType>::min();
00157 }
00158
00160 inline void combineRect(const Rect &r)
00161 {
00162 x1 = std::min(x1, r.x1);
00163 y1 = std::min(y1, r.y1);
00164 x2 = std::max(x2, r.x2);
00165 y2 = std::max(y2, r.y2);
00166 }
00167
00169 inline void combineRects(const Rect &a, const Rect &b)
00170 {
00171 x1 = std::min(a.x1, b.x1);
00172 y1 = std::min(a.y1, b.y1);
00173 x2 = std::max(a.x2, b.x2);
00174 y2 = std::max(a.y2, b.y2);
00175 }
00176
00178 inline void intersectRect(const Rect &a)
00179 {
00180 x1 = std::max(a.x1, x1);
00181 y1 = std::max(a.y1, y1);
00182 x2 = std::min(a.x2, x2);
00183 y2 = std::min(a.y2, y2);
00184 }
00185
00187 inline void intersectRects(const Rect &a, const Rect &b)
00188 {
00189 x1 = std::max(a.x1, b.x1);
00190 y1 = std::max(a.y1, b.y1);
00191 x2 = std::min(a.x2, b.x2);
00192 y2 = std::min(a.y2, b.y2);
00193 }
00194
00196 inline AreaType getArea() const
00197 {
00198 return static_cast<AreaType>(x2 - x1) * static_cast<AreaType>(y2 - y1);
00199 }
00200
00202 inline AreaType getIntersectingArea(const Rect &a) const
00203 {
00204 if (x2 < a.x1 || a.x2 < x1 || y2 < a.y2 || a.y2 < y2) return 0;
00205
00206 return static_cast<AreaType>(std::min(a.x2, x2) - std::max(a.x1, x1))
00207 * static_cast<AreaType>(std::min(a.y2, y2) - std::max(a.y1, y1));
00208 }
00209
00211 inline AreaType getMargin() const
00212 {
00213 return 2 * static_cast<AreaType>( (x2 - x1) + (y2 - y1) );
00214 }
00215
00217 inline Point getCenter() const
00218 {
00219 return Point(x1 + (x2 - x1) / 2, y1 + (y2 - y1) / 2);
00220 }
00221
00223 inline bool containsRect(const Rect &r) const
00224 {
00225 return (x1 <= r.x1) && (y1 <= r.y1) && (r.x2 <= x2) && (r.y2 <= y2);
00226 }
00227
00229 inline bool touchesRect(const Rect &r) const
00230 {
00231
00232 return (x1 == r.x1) || (y1 == r.y1) || (r.x2 == x2) || (r.y2 == y2);
00233 }
00234
00237 inline bool intersectsRect(const Rect &r) const
00238 {
00239 return (x1 <= r.x2 && x2 >= r.x1 && y1 <= r.y2 && y2 >= r.y1);
00240 }
00241 };
00242
00244 struct LevelStats
00245 {
00247 unsigned int nodes;
00248
00250 unsigned int children;
00251
00253 unsigned int unusedchildren;
00254
00256 unsigned int bytes;
00257
00259 unsigned int unusedbytes;
00260
00262 AreaType overlap;
00263
00265 AreaType wastearea;
00266
00268 inline LevelStats()
00269 {
00270 nodes = 0;
00271 children = 0;
00272 unusedchildren = 0;
00273 bytes = 0;
00274 unusedbytes = 0;
00275 overlap = 0;
00276 wastearea = 0;
00277 }
00278
00280 inline LevelStats & operator+=(const LevelStats &s)
00281 {
00282 nodes += s.nodes;
00283 children += s.children;
00284 unusedchildren += s.unusedchildren;
00285 bytes += s.bytes;
00286 unusedbytes += s.unusedbytes;
00287 overlap += s.overlap;
00288 wastearea += s.wastearea;
00289 return *this;
00290 }
00291 };
00292
00294 struct Stats
00295 {
00297 std::vector<LevelStats> level;
00298
00300 inline Stats()
00301 {
00302 }
00303 };
00304
00308 template <typename _DataType, typename _DataTypeCallback>
00309 class Tree
00310 {
00311 public:
00312
00313
00314 typedef _DataType DataType;
00315 typedef const _DataType& DataRef;
00316
00317 typedef _DataTypeCallback DataTypeCallback;
00318
00319 typedef unsigned int pageid_t;
00320
00321 static const unsigned int pagesize = 32;
00322
00323 static const unsigned int pageminfill = 12;
00324
00325 unsigned int reinsertnum;
00326
00327 public:
00328
00330 struct ReinsertDist
00331 {
00332 unsigned int childid;
00333 AreaType distance;
00334
00335 static inline bool order_distance(const ReinsertDist &a, const ReinsertDist &b)
00336 {
00337 return a.distance < b.distance;
00338 }
00339 static inline bool order_childid(const ReinsertDist &a, const ReinsertDist &b)
00340 {
00341 return a.childid < b.childid;
00342 }
00343 };
00344
00345 protected:
00347 class LeafNode;
00348 class InnerNode;
00349
00350 class InnerNodeData;
00351 class LeafNodeData;
00352
00354 class NodeHead
00355 {
00356 public:
00359 unsigned short level;
00360
00362 unsigned short childnum;
00363
00365 Rect nodeMBR;
00366
00367
00368
00370 inline void initializeRoot()
00371 {
00372 nodeMBR.setInfinite();
00373 level = 0;
00374 childnum = 0;
00375 }
00376
00378 inline void initializeSibling(unsigned int _level)
00379 {
00380 nodeMBR.setInfinite();
00381 level = _level;
00382 childnum = 0;
00383 }
00384 };
00385
00389 template <typename _NodeData>
00390 class Node : public NodeHead
00391 {
00392 public:
00394 typedef _NodeData NodeData;
00395
00397 typedef Node<NodeData> NodeType;
00398
00400 NodeData children[pagesize];
00401
00402
00403
00405 inline void recalcChildrenMBR(const Tree &tree, class Rect &dest) const
00406 {
00407 dest.setInfinite();
00408
00409 for(unsigned int ci = 0; ci < this->childnum; ci++)
00410 dest.combineRect(children[ci].getMBR(tree));
00411 }
00412
00415 unsigned int findLeastEnlargement(const Tree &tree, const Rect &newrect) const
00416 {
00417 AreaType area = std::numeric_limits<AreaType>::max();
00418 unsigned int bestchild = std::numeric_limits<unsigned int>::max();
00419
00420 Rect rt;
00421
00422
00423 for(unsigned int i = 0; i < this->childnum; i++)
00424 {
00425 rt.combineRects(newrect, children[i].getMBR(tree));
00426
00427 AreaType enlarge = rt.getArea() - children[i].getMBR(tree).getArea();
00428
00429 if (enlarge < area)
00430 {
00431 area = enlarge;
00432 bestchild = i;
00433 }
00434
00435 else if (enlarge == area)
00436 {
00437 if (rt.getArea() < children[bestchild].getMBR(tree).getArea())
00438 {
00439 bestchild = i;
00440 }
00441 }
00442 }
00443
00444 assert( bestchild < this->childnum );
00445
00446 return bestchild;
00447 }
00448
00451 unsigned int findLeastOverlap(const Tree &tree, const Rect &newrect) const
00452 {
00453 unsigned int min_bestchild = std::numeric_limits<unsigned int>::max();
00454 AreaType min_overlap = std::numeric_limits<AreaType>::max();
00455 AreaType min_enlarge = std::numeric_limits<AreaType>::max();
00456
00457 Rect rt, ru;
00458
00459 for (unsigned int ci = 0; ci < this->childnum; ci++)
00460 {
00461
00462 rt.combineRects(newrect, children[ci].getMBR(tree));
00463
00464 AreaType overlap = 0;
00465
00466
00467 for(unsigned int cj = 0; cj < this->childnum; cj++)
00468 {
00469 if (ci == cj) continue;
00470
00471 AreaType isa = rt.getIntersectingArea(children[cj].getMBR(tree));
00472
00473 if (isa > 0)
00474 {
00475 overlap += isa - children[ci].getMBR(tree).getIntersectingArea(children[cj].getMBR(tree));
00476 }
00477 }
00478
00479
00480 AreaType enlarge = rt.getArea() - children[ci].getMBR(tree).getArea();
00481
00482
00483 if (min_overlap > overlap)
00484 {
00485 min_bestchild = ci;
00486 min_overlap = overlap;
00487 min_enlarge = enlarge;
00488 }
00489
00490 else if (min_overlap == overlap)
00491 {
00492 if (min_enlarge > enlarge)
00493 {
00494 min_bestchild = ci;
00495 min_enlarge = enlarge;
00496 }
00497
00498 else if (min_enlarge == enlarge)
00499 {
00500 if (children[min_bestchild].getMBR(tree).getArea() > children[ci].getMBR(tree).getArea())
00501 {
00502 min_bestchild = ci;
00503 min_enlarge = enlarge;
00504 }
00505 }
00506 }
00507 }
00508
00509 assert( min_bestchild < this->childnum );
00510
00511 return min_bestchild;
00512 }
00513
00514
00515
00518 class NodeHead* chooseSubtree(Tree &tree, const Rect &newrect, unsigned int maxlevel, std::stack<pageid_t>& path)
00519 {
00520 if (this->level == maxlevel) return this;
00521
00522 #if defined(R_TREE_LINEAR) || defined(R_TREE_QUADRATIC)
00523
00524 unsigned int child = findLeastEnlargement(tree, newrect);
00525
00526 #elif defined(R_STAR_TREE)
00527
00528 unsigned int child;
00529 if (this->level == 1)
00530 {
00531 child = findLeastOverlap(tree, newrect);
00532 }
00533 else
00534 {
00535 child = findLeastEnlargement(tree, newrect);
00536 }
00537
00538 #endif
00539
00540 assert(this->level != 0);
00541 class InnerNode *in = reinterpret_cast<class InnerNode*>(this);
00542
00543 pageid_t childpage = in->children[child].page;
00544
00545 class NodeHead *childnode = tree.pageman.getPage(childpage);
00546 path.push(childpage);
00547
00548 if (childnode->level == 0) return childnode;
00549
00550 return static_cast<class InnerNode*>(childnode)->chooseSubtree(tree, newrect, maxlevel, path);
00551 }
00552
00554 class LeafNode* findLeaf(Tree &tree, const class LeafNodeData &rmdata, std::queue<pageid_t>& path)
00555 {
00556 if (this->level == 0)
00557 {
00558 LeafNode *ln = reinterpret_cast<LeafNode*>(this);
00559
00560
00561 for(unsigned int ci = 0; ci < ln->childnum; ci++)
00562 {
00563 if (ln->children[ci] == rmdata)
00564 {
00565 return ln;
00566 }
00567 }
00568 }
00569 else
00570 {
00571 InnerNode *in = reinterpret_cast<InnerNode*>(this);
00572
00573 Rect rmrect = rmdata.getMBR(tree);
00574
00575
00576
00577 for(unsigned int ci = 0; ci < in->childnum; ci++)
00578 {
00579 if (in->children[ci].getMBR(tree).containsRect(rmrect))
00580 {
00581 NodeHead *cn = tree.pageman.getPage(in->children[ci].page);
00582
00583 LeafNode *ret;
00584 if (cn->level == 0)
00585 ret = static_cast<LeafNode*>(cn)->findLeaf(tree, rmdata, path);
00586 else
00587 ret = static_cast<InnerNode*>(cn)->findLeaf(tree, rmdata, path);
00588
00589 if (ret)
00590 {
00591 path.push(in->children[ci].page);
00592 return ret;
00593 }
00594 }
00595 }
00596 }
00597 return NULL;
00598 }
00599
00601 void writeFig(const Tree &tree, std::ostream &o, int maxlevel) const
00602 {
00603 if (static_cast<int>(this->level) < maxlevel) return;
00604
00605 for(unsigned int ci = 0; ci < this->childnum; ci++)
00606 {
00607 if (this->level > 0)
00608 {
00609
00610 const InnerNode *in = reinterpret_cast<const InnerNode*>(this);
00611
00612 NodeHead *cn = tree.pageman.getPage(in->children[ci].page);
00613
00614 if (cn->level == 0)
00615 static_cast<LeafNode*>(cn)->writeFig(tree, o, maxlevel);
00616 else
00617 static_cast<InnerNode*>(cn)->writeFig(tree, o, maxlevel);
00618 }
00619
00620 const Rect &rect = children[ci].getMBR(tree);
00621
00622 if (rect.getArea() == 0) continue;
00623
00624
00625 o << "2 2 0 1 " << 32+this->level << " 7 " << 100-this->level << " -1 -1 0.000 0 0 -1 0 0 5\n"
00626 << " "
00627 << rect.x1 << " " << rect.y1 << " "
00628 << rect.x2 << " " << rect.y1 << " "
00629 << rect.x2 << " " << rect.y2 << " "
00630 << rect.x1 << " " << rect.y2 << " "
00631 << rect.x1 << " " << rect.y1 << "\n";
00632 }
00633 }
00634
00636 bool checkNode(const Tree &tree, unsigned int thislevel, unsigned int *numentries) const
00637 {
00638 assert(this->level == thislevel);
00639
00640 if (this->level > 0)
00641 {
00642
00643 const InnerNode *in = reinterpret_cast<const InnerNode*>(this);
00644
00645 for(unsigned int ci = 0; ci < in->childnum; ci++)
00646 {
00647 NodeHead *cn = tree.pageman.getPage(in->children[ci].page);
00648
00649 if (cn->level == 0) {
00650 if (!static_cast<const LeafNode*>(cn)->checkNode(tree, thislevel-1, numentries)) return false;
00651 }
00652 else {
00653 if (!static_cast<const InnerNode*>(cn)->checkNode(tree, thislevel-1, numentries)) return false;
00654 }
00655 }
00656 }
00657
00658
00659 Rect r;
00660 recalcChildrenMBR(tree, r);
00661 assert(r == this->nodeMBR);
00662
00663
00664 assert(this->childnum >= pageminfill or this->level == tree.levels);
00665
00666
00667 if (this->level == 0)
00668 numentries += this->childnum;
00669
00670 return true;
00671 }
00672
00674 void calcStats(const Tree &tree, Stats &s) const
00675 {
00676 AreaType overlap = 0;
00677
00678
00679 for(unsigned int ci = 0; ci < this->childnum; ci++)
00680 {
00681 for(unsigned int cj = ci+1; cj < this->childnum; cj++)
00682 {
00683 assert(ci != cj);
00684 overlap += children[ci].getMBR(tree).getIntersectingArea(children[cj].getMBR(tree));
00685 }
00686 }
00687
00688
00689
00690 AreaType waste = this->nodeMBR.getArea();
00691 Rect rup;
00692 rup.setInfinite();
00693
00694 for(unsigned int ci = 0; ci < this->childnum; ci++)
00695 {
00696 Rect rnew;
00697 rnew.intersectRects(rup, children[ci].getMBR(tree));
00698
00699 if (!rup.valid()) {
00700 waste -= rnew.getArea();
00701 }
00702 else {
00703 waste -= rnew.getArea() - rup.getArea();
00704 }
00705
00706 rup = rnew;
00707 }
00708
00709 assert(waste >= 0);
00710
00711
00712 LevelStats &ls = s.level.at(this->level);
00713
00714 ls.nodes++;
00715 ls.children += this->childnum;
00716 ls.unusedchildren += pagesize - this->childnum;
00717 ls.bytes += sizeof(*this);
00718 ls.unusedbytes += (pagesize - this->childnum) * sizeof(NodeData);
00719 ls.overlap += overlap;
00720 ls.wastearea += waste;
00721
00722 if (this->level > 0)
00723 {
00724
00725 const InnerNode *in = reinterpret_cast<const InnerNode*>(this);
00726
00727 for(unsigned int ci = 0; ci < in->childnum; ci++)
00728 {
00729 NodeHead *cn = tree.pageman.getPage(in->children[ci].page);
00730
00731 if (cn->level == 0)
00732 static_cast<LeafNode*>(cn)->calcStats(tree, s);
00733 else
00734 static_cast<InnerNode*>(cn)->calcStats(tree, s);
00735 }
00736 }
00737 }
00738
00740 AreaType calcOverlap(const Tree &tree) const
00741 {
00742 AreaType overlap = 0;
00743
00744 for(unsigned int ci = 0; ci < this->childnum; ci++)
00745 {
00746 for(unsigned int cj = ci+1; cj < this->childnum; cj++)
00747 {
00748 assert(ci != cj);
00749 overlap += children[ci].getMBR(tree).getIntersectingArea(children[cj].getMBR(tree));
00750 }
00751 }
00752
00753 if (this->level > 0)
00754 {
00755
00756 const InnerNode *in = reinterpret_cast<const InnerNode*>(this);
00757
00758 for(unsigned int ci = 0; ci < in->childnum; ci++)
00759 {
00760 NodeHead *cn = tree.pageman.getPage(in->children[ci].page);
00761
00762 if (cn->level == 0)
00763 overlap += static_cast<LeafNode*>(cn)->calcOverlap(tree);
00764 else
00765 overlap += static_cast<InnerNode*>(cn)->calcOverlap(tree);
00766 }
00767 }
00768
00769 return overlap;
00770 }
00771
00773 AreaType calcWasteArea(const Tree &tree) const
00774 {
00775 AreaType waste = this->nodeMBR.getArea();
00776 Rect rup;
00777 rup.setInfinite();
00778
00779 for(unsigned int ci = 0; ci < this->childnum; ci++)
00780 {
00781 Rect rnew;
00782 rnew.intersectRects(rup, children[ci].getMBR(tree));
00783
00784 if (!rup.valid()) {
00785 waste -= rnew.getArea();
00786 }
00787 else {
00788 waste -= rnew.getArea() - rup.getArea();
00789 }
00790
00791 rup = rnew;
00792 }
00793
00794 assert(waste >= 0);
00795
00796 if (this->level > 0)
00797 {
00798
00799 const InnerNode *in = reinterpret_cast<const InnerNode*>(this);
00800
00801 for(unsigned int ci = 0; ci < in->childnum; ci++)
00802 {
00803 NodeHead *cn = tree.pageman.getPage(in->children[ci].page);
00804
00805 if (cn->level == 0)
00806 waste += static_cast<LeafNode*>(cn)->calcWasteArea(tree);
00807 else
00808 waste += static_cast<InnerNode*>(cn)->calcWasteArea(tree);
00809 }
00810 }
00811
00812 return waste;
00813 }
00814
00815
00816
00819 bool insertChild(Tree &tree, pageid_t mypageid, const NodeData &newdata, std::stack<pageid_t>& path, char *overflowedLevel)
00820 {
00821 if (this->childnum < pagesize)
00822 {
00823
00824 this->children[this->childnum] = newdata;
00825 this->childnum++;
00826
00827
00828 if (not this->nodeMBR.containsRect(newdata.getMBR(tree)))
00829 {
00830 this->nodeMBR.combineRect(newdata.getMBR(tree));
00831
00832
00833 if (not path.empty())
00834 {
00835 pageid_t parentpage = path.top();
00836 path.pop();
00837
00838 NodeHead *parentnode = tree.pageman.getPage(parentpage);
00839 assert(parentnode->level != 0);
00840
00841 static_cast<InnerNode*>(parentnode)->adjustTree(tree, parentpage, *this, mypageid, path);
00842 }
00843 return true;
00844 }
00845 else
00846 return false;
00847 }
00848 #if defined(R_STAR_TREE)
00849 else if (!path.empty() && overflowedLevel[this->level] == 0 && tree.reinsertnum > 0)
00850 {
00851
00852 overflowedLevel[this->level] = 1;
00853
00854 reinsertData(tree, mypageid, newdata, path, overflowedLevel);
00855
00856 return true;
00857 }
00858 #endif
00859 else
00860 {
00861
00862 NodeType *nn;
00863 pageid_t nn_page;
00864
00865 splitNode(tree, newdata, &nn, nn_page);
00866
00867 if (path.empty())
00868 {
00869
00870
00871
00872
00873
00874 tree.rootpage = tree.pageman.new_innerpage();
00875 InnerNode *root = static_cast<InnerNode*>( tree.pageman.getPage(tree.rootpage) );
00876
00877 root->initializeRoot();
00878
00879 tree.levels++;
00880 root->level = this->level + 1;
00881 root->childnum = 2;
00882
00883 assert(root->level == tree.levels);
00884
00885 root->children[0].rect = this->nodeMBR;
00886 root->children[0].page = mypageid;
00887
00888 root->children[1].rect = nn->nodeMBR;
00889 root->children[1].page = nn_page;
00890
00891 root->nodeMBR.combineRects(this->nodeMBR, nn->nodeMBR);
00892 }
00893 else
00894 {
00895
00896
00897
00898
00899
00900 pageid_t parentpage = path.top();
00901 path.pop();
00902
00903 NodeHead *parentnode = tree.pageman.getPage(parentpage);
00904 assert(parentnode->level != 0);
00905
00906 static_cast<InnerNode*>(parentnode)->adjustTreeSplit(tree, parentpage,
00907 *this, mypageid,
00908 *nn, nn_page, path, overflowedLevel);
00909 }
00910
00911 return true;
00912 }
00913 }
00914
00916 void adjustTree(Tree &tree, pageid_t mypageid, const NodeHead& adj, pageid_t adjpage, std::stack<pageid_t>& path)
00917 {
00918
00919 unsigned int adjchild;
00920 for(adjchild = 0; adjchild < this->childnum; adjchild++)
00921 {
00922 if (this->children[adjchild].page == adjpage) break;
00923 }
00924
00925 assert(adjchild < this->childnum);
00926
00927 this->children[adjchild].rect = adj.nodeMBR;
00928
00929
00930
00931
00932
00933
00934 this->nodeMBR.combineRect(adj.nodeMBR);
00935
00936
00937 if (not path.empty())
00938 {
00939 pageid_t parentpage = path.top();
00940 path.pop();
00941
00942 NodeHead *parentnode = tree.pageman.getPage(parentpage);
00943 assert(parentnode->level != 0);
00944
00945 static_cast<InnerNode*>(parentnode)->adjustTree(tree, parentpage, *this, mypageid, path);
00946 }
00947 }
00948
00951 void adjustTreeSplit(Tree &tree, pageid_t mypageid, const NodeHead &adjN, pageid_t adjNpage, const NodeHead &adjNN, pageid_t adjNNpage, std::stack<pageid_t>& path, char *overflowedLevel)
00952 {
00953
00954 unsigned int adjchild;
00955 for(adjchild = 0; adjchild < this->childnum; adjchild++)
00956 {
00957 if (this->children[adjchild].page == adjNpage) break;
00958 }
00959
00960 assert(adjchild < this->childnum);
00961
00962
00963
00964
00965 this->children[adjchild].rect = adjN.nodeMBR;
00966
00967 this->nodeMBR.setInfinite();
00968
00969 for(unsigned int ci = 0; ci < this->childnum; ci++)
00970 this->nodeMBR.combineRect(this->children[ci].getMBR(tree));
00971
00972
00973 InnerNodeData newdata(adjNN.nodeMBR, adjNNpage);
00974 bool adjustedTree = insertChild(tree, mypageid, newdata, path, overflowedLevel);
00975
00976
00977
00978 if (!adjustedTree and not path.empty())
00979 {
00980 pageid_t parentpage = path.top();
00981 path.pop();
00982
00983 NodeHead *parentnode = tree.pageman.getPage(parentpage);
00984 static_cast<InnerNode*>(parentnode)->adjustTreeReinsert(tree, parentpage, *this, mypageid, path);
00985 }
00986 }
00987
00990 void adjustTreeReinsert(Tree &tree, pageid_t mypageid, const NodeHead &adj, pageid_t adjpage,std::stack<pageid_t>& path)
00991 {
00992
00993 unsigned int adjci;
00994 for(adjci = 0; adjci < this->childnum; adjci++)
00995 {
00996 if (this->children[adjci].page == adjpage) break;
00997 }
00998
00999 assert(adjci < this->childnum);
01000
01001
01002
01003
01004 this->children[adjci].rect = adj.nodeMBR;
01005
01006 this->nodeMBR.setInfinite();
01007
01008 for(unsigned int ci = 0; ci < this->childnum; ci++)
01009 this->nodeMBR.combineRect(this->children[ci].getMBR(tree));
01010
01011
01012 if (not path.empty())
01013 {
01014 pageid_t parentpage = path.top();
01015 path.pop();
01016
01017 NodeHead *parentnode = tree.pageman.getPage(parentpage);
01018 static_cast<InnerNode*>(parentnode)->adjustTreeReinsert(tree, parentpage, *this, mypageid, path);
01019 }
01020 }
01021
01023 void reinsertData(Tree &tree, pageid_t mypageid, const NodeData &newdata, std::stack<pageid_t>& path, char *overflowedLevel)
01024 {
01025 assert(this->childnum == pagesize);
01026
01027 std::vector<ReinsertDist> distlist(this->childnum+1);
01028
01029 Point mycenter = this->nodeMBR.getCenter();
01030
01031 for(unsigned int ci = 0; ci < this->childnum; ci++)
01032 {
01033 distlist[ci].childid = ci;
01034
01035 distlist[ci].distance = mycenter.getDistanceSquare( this->children[ci].getMBR(tree).getCenter() );
01036 assert(distlist[ci].distance >= 0);
01037 }
01038
01039 distlist[this->childnum].childid = this->childnum;
01040 distlist[this->childnum].distance = mycenter.getDistanceSquare( newdata.getMBR(tree).getCenter() );
01041 assert(distlist[this->childnum].distance >= 0);
01042
01043
01044 std::sort(distlist.begin(), distlist.end(), ReinsertDist::order_distance);
01045
01046
01047 unsigned int keptnum = (this->childnum+1) - tree.reinsertnum;
01048
01049
01050 std::vector<NodeData> reinsertLater(tree.reinsertnum);
01051
01052 for(unsigned int i = 0; i < tree.reinsertnum; i++)
01053 {
01054 if (distlist[keptnum+i].childid < this->childnum)
01055 {
01056 reinsertLater[i] = this->children[ distlist[keptnum+i].childid ];
01057 }
01058 else
01059 {
01060 reinsertLater[i] = newdata;
01061 }
01062 }
01063
01064
01065 std::sort(distlist.begin(), distlist.begin() + keptnum, ReinsertDist::order_childid);
01066
01067 this->nodeMBR.setInfinite();
01068
01069 for(unsigned int ci = 0; ci < keptnum; ci++)
01070 {
01071 if (distlist[ci].childid == ci)
01072 {
01073 this->nodeMBR.combineRect(this->children[ci].getMBR(tree));
01074 continue;
01075 }
01076
01077 if (distlist[ci].childid < this->childnum)
01078 {
01079 this->children[ci] = this->children[ distlist[ci].childid ];
01080 }
01081 else
01082 {
01083 this->children[ci] = newdata;
01084 }
01085
01086 this->nodeMBR.combineRect(this->children[ci].getMBR(tree));
01087 }
01088
01089 this->childnum = keptnum;
01090
01091
01092 assert(!path.empty());
01093 {
01094 pageid_t parentpage = path.top();
01095 path.pop();
01096
01097 NodeHead *parentnode = tree.pageman.getPage(parentpage);
01098 static_cast<InnerNode*>(parentnode)->adjustTreeReinsert(tree, parentpage, *this, mypageid, path);
01099 }
01100
01101
01102 for(unsigned int ri = 0; ri < tree.reinsertnum; ri++)
01103 {
01104 tree.reinsertRect(reinsertLater[ri], this->level, overflowedLevel);
01105 }
01106 }
01107
01109 void deleteChild(const Tree &tree, unsigned int ci)
01110 {
01111 assert(ci < this->childnum);
01112
01113
01114 if (this->childnum > 0 && ci+1 != this->childnum)
01115 {
01116 this->children[ci] = this->children[this->childnum-1];
01117 }
01118
01119 this->childnum--;
01120
01121
01122 recalcChildrenMBR(tree, this->nodeMBR);
01123 }
01124
01125
01126
01129 void splitNode(Tree &tree, const NodeData &newdata, NodeType** nndest, pageid_t &nn_page)
01130 {
01131
01132 std::vector<unsigned int> group1, group2;
01133
01134 #if defined(R_TREE_LINEAR) || defined(R_TREE_QUADRATIC)
01135
01136 splitNodeMakeGroups(tree, newdata.getMBR(tree), group1, group2);
01137
01138 #elif defined(R_STAR_TREE)
01139
01140 splitNodeMakeGroupsRStar(tree, newdata.getMBR(tree), group1, group2);
01141
01142 #endif
01143
01144
01145
01146 nn_page = tree.pageman.newPage( sizeof(NodeType) );
01147
01148 NodeType *n = new NodeType();
01149 NodeType *nn = static_cast<NodeType*>(tree.pageman.getPage(nn_page));
01150
01151 n->initializeSibling(this->level);
01152 nn->initializeSibling(this->level);
01153
01154 for(unsigned int gi = 0; gi < group1.size(); gi++)
01155 {
01156 unsigned int ci = group1[gi];
01157
01158 if (ci < this->childnum)
01159 {
01160 n->children[gi] = this->children[ci];
01161 }
01162 else
01163 {
01164
01165 n->children[gi] = newdata;
01166 }
01167 n->nodeMBR.combineRect(n->children[gi].getMBR(tree));
01168 }
01169 n->childnum = static_cast<unsigned short>(group1.size());
01170
01171 for(unsigned int gi = 0; gi < group2.size(); gi++)
01172 {
01173 unsigned int ci = group2[gi];
01174
01175 if (ci < this->childnum)
01176 {
01177 nn->children[gi] = this->children[ci];
01178 }
01179 else
01180 {
01181
01182 nn->children[gi] = newdata;
01183 }
01184 nn->nodeMBR.combineRect(nn->children[gi].getMBR(tree));
01185 }
01186 nn->childnum = static_cast<unsigned short>(group2.size());
01187
01188
01189 *this = *n;
01190 delete n;
01191
01192 *nndest = nn;
01193 }
01194
01197 void splitNodeMakeGroups(const Tree &tree, const Rect &newrect, std::vector<unsigned int> &group1, std::vector<unsigned int> &group2) const
01198 {
01199 unsigned int seed1, seed2;
01200
01201 #if defined(R_TREE_LINEAR)
01202
01203 pickSeedsLinear(tree, newrect, seed1, seed2);
01204
01205 #elif defined(R_TREE_QUADRATIC)
01206
01207 pickSeedsQuadratic(tree, newrect, seed1, seed2);
01208
01209 #else
01210 assert(0);
01211 #endif
01212
01213 assert(seed1 <= this->childnum);
01214 assert(seed2 <= this->childnum);
01215 assert(seed1 != seed2);
01216
01217 group1.push_back(seed1);
01218 group2.push_back(seed2);
01219
01220
01221 char cmask[pagesize+1];
01222 memset(cmask, 0, pagesize+1);
01223
01224 cmask[seed1] = 1;
01225 cmask[seed2] = 1;
01226
01227
01228 Rect mbr1 = (seed1 < this->childnum) ? children[seed1].getMBR(tree) : newrect;
01229 Rect mbr2 = (seed2 < this->childnum) ? children[seed2].getMBR(tree) : newrect;
01230
01231 unsigned int num_ungrouped = (this->childnum + 1) - 2;
01232
01233 unsigned int min_pageload = static_cast<unsigned int>(pagesize * 0.5);
01234
01235 while(num_ungrouped > 0)
01236 {
01237
01238
01239 if (group1.size() + num_ungrouped <= min_pageload)
01240 {
01241
01242 for(unsigned int ci = 0; ci < this->childnum; ci++)
01243 {
01244 if (cmask[ci]) continue;
01245
01246 group1.push_back(ci);
01247 cmask[ci] = 1;
01248 num_ungrouped--;
01249 }
01250 if (!cmask[this->childnum])
01251 {
01252 group1.push_back(this->childnum);
01253 cmask[this->childnum] = 1;
01254 num_ungrouped--;
01255 }
01256 break;
01257 }
01258 else if (group2.size() + num_ungrouped <= min_pageload)
01259 {
01260
01261 for(unsigned int ci = 0; ci < this->childnum; ci++)
01262 {
01263 if (cmask[ci]) continue;
01264
01265 group2.push_back(ci);
01266 cmask[ci] = 1;
01267 num_ungrouped--;
01268 }
01269 if (!cmask[this->childnum])
01270 {
01271 group2.push_back(this->childnum);
01272 cmask[this->childnum] = 1;
01273 num_ungrouped--;
01274 }
01275 break;
01276 }
01277 else
01278 {
01279
01280
01281
01282
01283
01284
01285
01286 unsigned int childsel = std::numeric_limits<unsigned int>::max();
01287 AreaType childmaxdiff = std::numeric_limits<AreaType>::min();
01288
01289 AreaType childsel_inc1 = std::numeric_limits<AreaType>::min(),
01290 childsel_inc2 = std::numeric_limits<AreaType>::min();
01291
01292 Rect tr_group1, tr_group2;
01293
01294 AreaType area_mbr1 = mbr1.getArea();
01295 AreaType area_mbr2 = mbr2.getArea();
01296
01297 for(unsigned int ci = 0; ci < this->childnum; ci++)
01298 {
01299 if (cmask[ci]) continue;
01300
01301 tr_group1.combineRects(mbr1, children[ci].getMBR(tree));
01302 tr_group2.combineRects(mbr2, children[ci].getMBR(tree));
01303
01304 assert(tr_group1.getArea() >= area_mbr1);
01305 assert(tr_group2.getArea() >= area_mbr2);
01306
01307 AreaType increase1 = tr_group1.getArea() - area_mbr1;
01308 AreaType increase2 = tr_group2.getArea() - area_mbr2;
01309
01310 AreaType diff = std::max(increase1 - increase2,
01311 increase2 - increase1);
01312
01313 if (childmaxdiff < diff)
01314 {
01315 childmaxdiff = diff;
01316 childsel = ci;
01317 childsel_inc1 = increase1;
01318 childsel_inc2 = increase2;
01319 }
01320 }
01321 {
01322
01323 if (!cmask[this->childnum])
01324 {
01325 tr_group1.combineRects(mbr1, newrect);
01326 tr_group2.combineRects(mbr2, newrect);
01327
01328 AreaType increase1 = tr_group1.getArea() - area_mbr1;
01329 AreaType increase2 = tr_group2.getArea() - area_mbr2;
01330
01331 AreaType diff = std::max(increase1 - increase2,
01332 increase2 - increase1);
01333
01334 if (childmaxdiff < diff)
01335 {
01336 childmaxdiff = diff;
01337 childsel = this->childnum;
01338 childsel_inc1 = increase1;
01339 childsel_inc2 = increase2;
01340 }
01341 }
01342 }
01343
01344 assert(childsel <= this->childnum);
01345
01346
01347
01348 int group = 0;
01349 if (childsel_inc1 < childsel_inc2)
01350 {
01351 group = 1;
01352 }
01353 else if (childsel_inc2 < childsel_inc1)
01354 {
01355 group = 2;
01356 }
01357
01358 else if (area_mbr1 < area_mbr2)
01359 {
01360 group = 1;
01361 }
01362 else if (area_mbr2 < area_mbr1)
01363 {
01364 group = 2;
01365 }
01366
01367 else if (group1.size() < group2.size())
01368 {
01369 group = 1;
01370 }
01371 else if (group2.size() < group1.size())
01372 {
01373 group = 2;
01374 }
01375
01376 else
01377 {
01378 group = 1 + (childsel % 2);
01379 }
01380
01381
01382 if (group == 1)
01383 {
01384 group1.push_back(childsel);
01385
01386 if (childsel < this->childnum)
01387 mbr1.combineRect(children[childsel].getMBR(tree));
01388 else
01389 mbr1.combineRect(newrect);
01390 }
01391 else if (group == 2)
01392 {
01393 group2.push_back(childsel);
01394
01395 if (childsel < this->childnum)
01396 mbr2.combineRect(children[childsel].getMBR(tree));
01397 else
01398 mbr2.combineRect(newrect);
01399 }
01400 else {
01401 assert(0);
01402 }
01403
01404 cmask[childsel] = 1;
01405 num_ungrouped--;
01406 }
01407 }
01408
01409 assert(group1.size() + group2.size() == static_cast<unsigned int>(this->childnum) + 1);
01410 assert(group1.size() >= pageminfill);
01411 assert(group2.size() >= pageminfill);
01412
01413 #if 0
01414 std::cerr << "selected groups: " << std::endl;
01415 std::cerr << "g1:";
01416 for(unsigned int i = 0; i < group1.size(); i++)
01417 std::cerr << " " << group1[i];
01418 std::cerr << std::endl;
01419 std::cerr << "g2:";
01420 for(unsigned int i = 0; i < group2.size(); i++)
01421 std::cerr << " " << group2[i];
01422 std::cerr << std::endl;
01423 #endif
01424 }
01425
01427 void pickSeedsQuadratic(const Tree &tree, const Rect &newrect, unsigned int &seed1, unsigned int &seed2) const
01428 {
01429 Rect rt;
01430 AreaType max_inefficiency = std::numeric_limits<AreaType>::min();
01431
01432
01433 for(unsigned int i = 0; i < this->childnum; i++)
01434 {
01435 AreaType areaE1 = children[i].getMBR(tree).getArea();
01436
01437 for(unsigned int j = i+1; j < this->childnum; j++)
01438 {
01439 rt.combineRects(children[i].getMBR(tree), children[j].getMBR(tree));
01440
01441 AreaType d = rt.getArea() - areaE1 - children[j].getMBR(tree).getArea();
01442
01443 if (d > max_inefficiency)
01444 {
01445 max_inefficiency = d;
01446 seed1 = i;
01447 seed2 = j;
01448 }
01449 }
01450
01451
01452 {
01453 rt.combineRects(children[i].getMBR(tree), newrect);
01454
01455 AreaType d = rt.getArea() - areaE1 - newrect.getArea();
01456
01457 if (d > max_inefficiency)
01458 {
01459 max_inefficiency = d;
01460 seed1 = i;
01461 seed2 = this->childnum;
01462 }
01463 }
01464 }
01465 }
01466
01468 void pickSeedsLinear(const Tree &tree, const Rect &newrect, unsigned int &seed1, unsigned int &seed2) const
01469 {
01470
01471
01472
01473
01474 CoordType max_x1, min_x2;
01475 unsigned int max_x1_ci, min_x2_ci;
01476
01477 CoordType min_x1, max_x2;
01478
01479 double normalized_x;
01480
01481 {
01482
01483 min_x1 = max_x1 = newrect.x1;
01484 min_x2 = max_x2 = newrect.x2;
01485 max_x1_ci = this->childnum;
01486 min_x2_ci = this->childnum;
01487
01488 for(unsigned int ci = 0; ci < this->childnum; ci++)
01489 {
01490 if (max_x1 < children[ci].getMBR(tree).x1)
01491 {
01492 max_x1 = children[ci].getMBR(tree).x1;
01493 max_x1_ci = ci;
01494 }
01495 min_x1 = std::min(min_x1, children[ci].getMBR(tree).x1);
01496
01497 if (min_x2 > children[ci].getMBR(tree).x2)
01498 {
01499 min_x2 = children[ci].getMBR(tree).x2;
01500 min_x2_ci = ci;
01501 }
01502 max_x2 = std::min(max_x2, children[ci].getMBR(tree).x2);
01503 }
01504
01505 CoordType separation = max_x1 - min_x2;
01506
01507 CoordType width = max_x2 - min_x1;
01508 if (width <= 0) width = 1;
01509
01510 normalized_x = static_cast<double>(separation) / static_cast<double>(width);
01511 }
01512
01513
01514
01515 CoordType max_y1, min_y2;
01516 unsigned int max_y1_ci, min_y2_ci;
01517
01518 CoordType min_y1, max_y2;
01519
01520 double normalized_y;
01521
01522 {
01523
01524 min_y1 = max_y1 = newrect.y1;
01525 min_y2 = max_y2 = newrect.y2;
01526 max_y1_ci = this->childnum;
01527 min_y2_ci = this->childnum;
01528
01529 for(unsigned int ci = 0; ci < this->childnum; ci++)
01530 {
01531 if (max_y1 < children[ci].getMBR(tree).y1)
01532 {
01533 max_y1 = children[ci].getMBR(tree).y1;
01534 max_y1_ci = ci;
01535 }
01536 min_y1 = std::min(min_y1, children[ci].getMBR(tree).y1);
01537
01538 if (min_y2 > children[ci].getMBR(tree).y2)
01539 {
01540 min_y2 = children[ci].getMBR(tree).y2;
01541 min_y2_ci = ci;
01542 }
01543 max_y2 = std::min(max_y2, children[ci].getMBR(tree).y2);
01544 }
01545
01546 CoordType separation = max_y1 - min_y2;
01547
01548 CoordType width = max_y2 - min_y1;
01549 if (width <= 0) width = 1;
01550
01551 normalized_y = static_cast<double>(separation) / static_cast<double>(width);
01552 }
01553
01554 if (normalized_y > normalized_x)
01555 {
01556
01557 max_x1_ci = max_y1_ci;
01558 min_x2_ci = min_y2_ci;
01559 }
01560 else {
01561
01562 }
01563
01564
01565 if (max_x1_ci == min_x2_ci)
01566 {
01567 if (min_x2_ci == 0) min_x2_ci++;
01568 else min_x2_ci--;
01569 }
01570
01571 seed1 = max_x1_ci;
01572 seed2 = min_x2_ci;
01573 }
01574
01576 struct SplitDist
01577 {
01578 unsigned int childid;
01579 Rect mbr;
01580
01581 static inline bool cmp_axis1_lower(const SplitDist &a, const SplitDist &b)
01582 {
01583 return a.mbr.x1 < b.mbr.x1;
01584 }
01585 static inline bool cmp_axis1_upper(const SplitDist &a, const SplitDist &b)
01586 {
01587 return a.mbr.x2 < b.mbr.x2;
01588 }
01589 static inline bool cmp_axis2_lower(const SplitDist &a, const SplitDist &b)
01590 {
01591 return a.mbr.y1 < b.mbr.y1;
01592 }
01593 static inline bool cmp_axis2_upper(const SplitDist &a, const SplitDist &b)
01594 {
01595 return a.mbr.y2 < b.mbr.y2;
01596 }
01597
01598 typedef bool (*cmpfunc_t)(const SplitDist &a, const SplitDist &b);
01599
01600 static inline cmpfunc_t get_cmpfunc(unsigned int axis, unsigned int lower_upper)
01601 {
01602 if (axis == 0) {
01603 if (lower_upper == 0) return cmp_axis1_lower;
01604 if (lower_upper == 1) return cmp_axis1_upper;
01605 }
01606 if (axis == 1) {
01607 if (lower_upper == 0) return cmp_axis2_lower;
01608 if (lower_upper == 1) return cmp_axis2_upper;
01609 }
01610 assert(0);
01611 return cmp_axis1_lower;
01612 }
01613 };
01614
01617 void splitNodeMakeGroupsRStar(const Tree &tree, const Rect &newrect, std::vector<unsigned int> &group1, std::vector<unsigned int> &group2) const
01618 {
01619 assert(this->childnum == pagesize);
01620
01621 std::vector<SplitDist> distlower(this->childnum+1);
01622 std::vector<SplitDist> distupper(this->childnum+1);
01623
01624 for(unsigned int ci = 0; ci < this->childnum; ci++)
01625 {
01626 distlower[ci].childid = ci;
01627 distlower[ci].mbr = children[ci].getMBR(tree);
01628
01629 distupper[ci].childid = ci;
01630 distupper[ci].mbr = children[ci].getMBR(tree);
01631 }
01632
01633 distlower[this->childnum].childid = this->childnum;
01634 distlower[this->childnum].mbr = newrect;
01635
01636 distupper[this->childnum].childid = this->childnum;
01637 distupper[this->childnum].mbr = newrect;
01638
01639
01640
01641 AreaType minMargin = std::numeric_limits<AreaType>::max();
01642 int splitAxis = -1;
01643 int splitIndex = -1;
01644
01645 unsigned int distnum = this->childnum - 2*pageminfill + 2;
01646
01647 {
01648
01649 std::sort(distlower.begin(), distlower.end(), SplitDist::cmp_axis1_lower);
01650 std::sort(distupper.begin(), distupper.end(), SplitDist::cmp_axis1_upper);
01651
01652 Rect bb_lower_group1, bb_upper_group1;
01653 Rect bb_lower_group2, bb_upper_group2;
01654
01655 AreaType margin_lower = 0;
01656 AreaType margin_upper = 0;
01657
01658
01659 for(unsigned int di = 0; di < distnum; di++)
01660 {
01661 bb_lower_group1.setInfinite();
01662 bb_upper_group1.setInfinite();
01663
01664 unsigned int listsplit = pageminfill + di;
01665
01666 for(unsigned int i = 0; i < listsplit; i++)
01667 {
01668 bb_lower_group1.combineRect(distlower[i].mbr);
01669 bb_upper_group1.combineRect(distupper[i].mbr);
01670 }
01671
01672 bb_lower_group2.setInfinite();
01673 bb_upper_group2.setInfinite();
01674
01675 for(unsigned int i = listsplit; i < static_cast<unsigned int>(this->childnum+1); i++)
01676 {
01677 bb_lower_group2.combineRect(distlower[i].mbr);
01678 bb_upper_group2.combineRect(distupper[i].mbr);
01679 }
01680
01681
01682 margin_lower += bb_lower_group1.getMargin() + bb_lower_group2.getMargin();
01683 margin_upper += bb_upper_group1.getMargin() + bb_upper_group2.getMargin();
01684 }
01685
01686 AreaType margin = std::min(margin_lower, margin_upper);
01687
01688
01689 if (minMargin > margin)
01690 {
01691 minMargin = margin;
01692 splitAxis = 0;
01693 splitIndex = (margin_lower < margin_upper) ? 0 : 1;
01694 }
01695 }
01696 {
01697
01698 std::sort(distlower.begin(), distlower.end(), SplitDist::cmp_axis2_lower);
01699 std::sort(distupper.begin(), distupper.end(), SplitDist::cmp_axis2_upper);
01700
01701 Rect bb_lower_group1, bb_upper_group1;
01702 Rect bb_lower_group2, bb_upper_group2;
01703
01704 AreaType margin_lower = 0;
01705 AreaType margin_upper = 0;
01706
01707
01708 for(unsigned int di = 0; di < distnum; di++)
01709 {
01710 bb_lower_group1.setInfinite();
01711 bb_upper_group1.setInfinite();
01712
01713 unsigned int listsplit = pageminfill + di;
01714
01715 for(unsigned int i = 0; i < listsplit; i++)
01716 {
01717 bb_lower_group1.combineRect(distlower[i].mbr);
01718 bb_upper_group1.combineRect(distupper[i].mbr);
01719 }
01720
01721 bb_lower_group2.setInfinite();
01722 bb_upper_group2.setInfinite();
01723
01724 for(unsigned int i = listsplit; i < static_cast<unsigned int>(this->childnum+1); i++)
01725 {
01726 bb_lower_group2.combineRect(distlower[i].mbr);
01727 bb_upper_group2.combineRect(distupper[i].mbr);
01728 }
01729
01730
01731 margin_lower += bb_lower_group1.getMargin() + bb_lower_group2.getMargin();
01732 margin_upper += bb_upper_group1.getMargin() + bb_upper_group2.getMargin();
01733 }
01734
01735 AreaType margin = std::min(margin_lower, margin_upper);
01736 assert(margin >= 0);
01737
01738
01739 if (minMargin > margin)
01740 {
01741 minMargin = margin;
01742 splitAxis = 1;
01743 splitIndex = (margin_lower < margin_upper) ? 0 : 1;
01744 }
01745 }
01746
01747
01748 std::sort(distlower.begin(), distlower.end(), SplitDist::get_cmpfunc(splitAxis, splitIndex));
01749
01750
01751
01752 unsigned int min_distrib = distnum;
01753 AreaType min_overlap = std::numeric_limits<AreaType>::max();
01754 AreaType min_area = std::numeric_limits<AreaType>::max();
01755 {
01756 Rect bb_group1, bb_group2;
01757
01758
01759 for(unsigned int di = 0; di < distnum; di++)
01760 {
01761 bb_group1.setInfinite();
01762
01763 unsigned int listsplit = pageminfill + di;
01764
01765 for(unsigned int i = 0; i < listsplit; i++)
01766 {
01767 bb_group1.combineRect(distlower[i].mbr);
01768 }
01769
01770 bb_group2.setInfinite();
01771
01772 for(unsigned int i = listsplit; i < static_cast<unsigned int>(this->childnum+1); i++)
01773 {
01774 bb_group2.combineRect(distlower[i].mbr);
01775 }
01776
01777 AreaType overlap = bb_group1.getIntersectingArea(bb_group2);
01778 assert(overlap >= 0);
01779
01780 if (min_overlap > overlap)
01781 {
01782 min_distrib = di;
01783 min_overlap = overlap;
01784 min_area = bb_group1.getArea() + bb_group2.getArea();
01785 }
01786
01787 else if (min_overlap == overlap)
01788 {
01789 if (bb_group1.getArea() + bb_group2.getArea() < min_area)
01790 {
01791 min_distrib = di;
01792 min_overlap = overlap;
01793 min_area = bb_group1.getArea() + bb_group2.getArea();
01794 }
01795 }
01796 }
01797 assert(min_distrib < distnum);
01798 }
01799
01800
01801 {
01802 unsigned int listsplit = pageminfill + min_distrib;
01803
01804 for(unsigned int i = 0; i < listsplit; i++)
01805 {
01806 group1.push_back(distlower[i].childid);
01807 }
01808
01809 for(unsigned int i = listsplit; i < static_cast<unsigned int>(this->childnum+1); i++)
01810 {
01811 group2.push_back(distlower[i].childid);
01812 }
01813 }
01814
01815 assert(group1.size() + group2.size() == static_cast<unsigned int>(this->childnum) + 1);
01816 assert(group1.size() >= pageminfill);
01817 assert(group2.size() >= pageminfill);
01818 }
01819
01821 void condenseTree(Tree &tree, pageid_t mypageid, std::stack<pageid_t>& toReinsert, std::queue<pageid_t>& path)
01822 {
01823 if (path.empty())
01824 {
01825
01826 if (this->level != 0 && this->childnum == 1)
01827 {
01828 InnerNode *in = reinterpret_cast<InnerNode*>(this);
01829
01830 tree.rootpage = in->children[0].page;
01831
01832 tree.levels--;
01833
01834 tree.pageman.deletePage(mypageid);
01835 }
01836 }
01837 else
01838 {
01839
01840 pageid_t parentpage = path.front();
01841 path.pop();
01842
01843 InnerNode *parentnode = static_cast<InnerNode*>(tree.pageman.getPage(parentpage));
01844 assert(parentnode->level != 0);
01845
01846
01847 unsigned int ci;
01848 for(ci = 0; ci < parentnode->childnum; ci++)
01849 {
01850 if (parentnode->children[ci].page == mypageid) break;
01851 }
01852
01853 assert(ci < parentnode->childnum);
01854
01855 if (this->childnum < pageminfill)
01856 {
01857
01858 parentnode->deleteChild(tree, ci);
01859
01860 toReinsert.push(mypageid);
01861 }
01862 else
01863 {
01864
01865 parentnode->children[ci].rect = this->nodeMBR;
01866
01867 parentnode->recalcChildrenMBR(tree, parentnode->nodeMBR);
01868 }
01869
01870
01871 parentnode->condenseTree(tree, parentpage, toReinsert, path);
01872 }
01873 }
01874 };
01875
01877 struct InnerNodeData
01878 {
01879 public:
01881 Rect rect;
01882
01884 pageid_t page;
01885
01887 inline InnerNodeData()
01888 { }
01889
01891 inline InnerNodeData(const Rect &r, pageid_t p)
01892 : rect(r), page(p)
01893 { }
01894
01896 inline const class Rect getMBR(const Tree &) const
01897 { return rect; }
01898 };
01899
01901 class InnerNode : public Node<InnerNodeData>
01902 {
01903 public:
01904
01905 };
01906
01908 class LeafNodeData : public DataType
01909 {
01910 public:
01911 LeafNodeData() : DataType()
01912 { }
01913
01915 LeafNodeData(const DataType &init) : _DataType(init)
01916 { }
01917
01919 inline const class Rect getMBR(const Tree &tree) const
01920 { return tree.DTCallback->getMBR(*static_cast<const DataType*>(this)); }
01921 };
01922
01924 class LeafNode : public Node<LeafNodeData>
01925 {
01926 public:
01928 void deleteDataLeaf(Tree &tree, pageid_t mypageid, const LeafNodeData &rmdata, std::queue<pageid_t>& path)
01929 {
01930 assert(this->level == 0);
01931
01932
01933
01934 unsigned int ci;
01935 for(ci = 0; ci < this->childnum; ci++)
01936 {
01937 if (this->children[ci] == rmdata) break;
01938 }
01939
01940 assert(ci < this->childnum);
01941
01942
01943 if (this->childnum > 0 && ci+1 != this->childnum)
01944 {
01945 this->children[ci] = this->children[this->childnum-1];
01946 }
01947
01948 this->childnum--;
01949
01950
01951 recalcChildrenMBR(tree, this->nodeMBR);
01952
01953
01954
01955 std::stack<pageid_t> toReinsert;
01956 condenseTree(tree, mypageid, toReinsert, path);
01957
01958
01959 while(!toReinsert.empty())
01960 {
01961 pageid_t delpage = toReinsert.top();
01962 toReinsert.pop();
01963
01964 NodeHead *delnode = tree.pageman.getPage(delpage);
01965
01966 if (delnode->level == 0)
01967 {
01968 LeafNode *ln = static_cast<LeafNode*>(delnode);
01969
01970 for(unsigned int ci = 0; ci < ln->childnum; ci++)
01971 {
01972 char *overflowedLevel = static_cast<char*>(alloca(tree.levels+1));
01973 memset(overflowedLevel, 0, tree.levels+1);
01974
01975 tree.reinsertRect(ln->children[ci], 0, overflowedLevel);
01976 }
01977 }
01978 else
01979 {
01980 InnerNode *in = static_cast<InnerNode*>(delnode);
01981
01982 for(unsigned int ci = 0; ci < in->childnum; ci++)
01983 {
01984 char *overflowedLevel = static_cast<char*>(alloca(tree.levels+1));
01985 memset(overflowedLevel, 0, tree.levels+1);
01986
01987 tree.reinsertRect(in->children[ci], in->level, overflowedLevel);
01988 }
01989 }
01990
01991 tree.pageman.deletePage(delpage);
01992 }
01993 }
01994 };
01995
01996
01997
01999 template <typename NodeData>
02000 void reinsertRect(NodeData &newdata, unsigned int maxlevel, char *overflowedLevel)
02001 {
02002 NodeHead *root = pageman.getPage(rootpage);
02003
02004
02005 std::stack<pageid_t> path;
02006
02007 path.push(rootpage);
02008 class NodeHead *node;
02009 if (root->level == 0)
02010 node = static_cast<LeafNode*>(root)->chooseSubtree(*this, newdata.getMBR(*this), maxlevel, path);
02011 else
02012 node = static_cast<InnerNode*>(root)->chooseSubtree(*this, newdata.getMBR(*this), maxlevel, path);
02013
02014 assert(node);
02015 assert(node->level == maxlevel);
02016
02017 pageid_t page = path.top();
02018 path.pop();
02019 static_cast<Node<NodeData>*>(node)->insertChild(*this, page, newdata, path, overflowedLevel);
02020 }
02021
02023 class PageManager
02024 {
02025 public:
02026 typedef std::vector<class InnerNode*> innerpages_t;
02027 std::vector<class InnerNode*> innerpages;
02028
02029 typedef std::vector<class LeafNode*> leafpages_t;
02030 std::vector<class LeafNode*> leafpages;
02031
02032 PageManager()
02033 { }
02034
02035 PageManager(const PageManager &c)
02036 {
02037 for(unsigned int i = 0; i < c.innerpages.size(); i++)
02038 innerpages.push_back( new InnerNode(*c.innerpages[i]) );
02039
02040 for(unsigned int i = 0; i < c.leafpages.size(); i++)
02041 leafpages.push_back( new LeafNode(*c.leafpages[i]) );
02042 }
02043
02044 PageManager& operator=(const PageManager &c)
02045 {
02046 clear();
02047
02048 for(unsigned int i = 0; i < c.innerpages.size(); i++)
02049 innerpages.push_back( new InnerNode(*c.innerpages[i]) );
02050
02051 for(unsigned int i = 0; i < c.leafpages.size(); i++)
02052 leafpages.push_back( new LeafNode(*c.leafpages[i]) );
02053
02054 return *this;
02055 }
02056
02057 ~PageManager()
02058 {
02059 for(unsigned int pi = 0; pi < innerpages.size(); pi++)
02060 delete innerpages[pi];
02061
02062 for(unsigned int pi = 0; pi < leafpages.size(); pi++)
02063 delete leafpages[pi];
02064 }
02065
02066 static const pageid_t leafmask = 0x80000000;
02067
02068 class NodeHead* getPage(pageid_t pi) const
02069 {
02070 if (pi & leafmask)
02071 {
02072 assert((pi & ~leafmask) < leafpages.size());
02073 assert(leafpages[(pi & ~leafmask)]);
02074 return leafpages[(pi & ~leafmask)];
02075 }
02076 else
02077 {
02078 assert(pi < innerpages.size());
02079 assert(innerpages[pi]);
02080 return innerpages[pi];
02081 }
02082 }
02083
02084 pageid_t new_innerpage()
02085 {
02086 for(pageid_t pi = 0; pi < innerpages.size(); pi++)
02087 {
02088 if (innerpages[pi] == static_cast<InnerNode*>(NULL))
02089 {
02090 innerpages[pi] = new InnerNode;
02091 return pi;
02092 }
02093 }
02094
02095 innerpages.push_back(new InnerNode);
02096 return static_cast<pageid_t>(innerpages.size()-1);
02097 }
02098
02100 pageid_t new_leafpage()
02101 {
02102 for(pageid_t pi = 0; pi < leafpages.size(); pi++)
02103 {
02104 if (leafpages[pi] == static_cast<LeafNode*>(NULL))
02105 {
02106 leafpages[pi] = new LeafNode;
02107 return pi | leafmask;
02108 }
02109 }
02110
02111 leafpages.push_back(new LeafNode);
02112 return static_cast<pageid_t>((leafpages.size()-1) | leafmask);
02113 }
02114
02117 pageid_t newPage(unsigned int nodesize)
02118 {
02119 assert( sizeof(InnerNode) != sizeof(LeafNode) );
02120
02121 if (nodesize == sizeof(InnerNode))
02122 return new_innerpage();
02123 else if (nodesize == sizeof(LeafNode))
02124 return new_leafpage();
02125 else {
02126 assert(0);
02127 return new_innerpage();
02128 }
02129 }
02130
02131 void deletePage(pageid_t pi)
02132 {
02133 if (pi & leafmask)
02134 {
02135 assert((pi & ~leafmask) < leafpages.size());
02136 assert(leafpages[pi & ~leafmask]);
02137 delete leafpages[pi & ~leafmask];
02138 leafpages[pi & ~leafmask] = NULL;
02139 }
02140 else
02141 {
02142 assert(pi < innerpages.size());
02143 assert(innerpages[pi]);
02144 delete innerpages[pi];
02145 innerpages[pi] = NULL;
02146 }
02147 }
02148
02149 void clear()
02150 {
02151 for(unsigned int pi = 0; pi < innerpages.size(); pi++)
02152 delete innerpages[pi];
02153
02154 for(unsigned int pi = 0; pi < leafpages.size(); pi++)
02155 delete leafpages[pi];
02156
02157 innerpages.clear();
02158 leafpages.clear();
02159 }
02160 };
02161
02162 private:
02163
02164
02165 pageid_t rootpage;
02166
02167 PageManager pageman;
02168
02169 unsigned int levels;
02170
02171 unsigned int entries;
02172
02173 mutable DataTypeCallback *DTCallback;
02174
02175 public:
02176
02177
02178 explicit Tree(DataTypeCallback *cb)
02179 {
02180 rootpage = pageman.new_leafpage();
02181
02182 NodeHead *root = pageman.getPage(rootpage);
02183 root->initializeRoot();
02184
02185 levels = 0;
02186 entries = 0;
02187 DTCallback = cb;
02188
02189 reinsertnum = pagesize - pageminfill;
02190 assert(pageminfill + reinsertnum <= pagesize);
02191 }
02192
02194 Tree(const Tree &o)
02195 {
02196 rootpage = o.rootpage;
02197 pageman = o.pageman;
02198
02199 levels = o.levels;
02200 entries = o.entries;
02201 reinsertnum = o.reinsertnum;
02202 DTCallback = o.DTCallback;
02203 }
02204
02206 Tree& operator=(const Tree &o)
02207 {
02208 rootpage = o.rootpage;
02209 pageman = o.pageman;
02210
02211 levels = o.levels;
02212 entries = o.entries;
02213 reinsertnum = o.reinsertnum;
02214
02215 return *this;
02216 }
02217
02219 void clear()
02220 {
02221 pageman.clear();
02222
02223 rootpage = pageman.new_leafpage();
02224
02225 NodeHead *root = pageman.getPage(rootpage);
02226 root->initializeRoot();
02227
02228 levels = 0;
02229 entries = 0;
02230
02231 assert(pageminfill + reinsertnum <= pagesize);
02232 }
02233
02235 void setCallback(DataTypeCallback *newcb)
02236 {
02237 DTCallback = newcb;
02238 }
02239
02241 void setReinsertNum(int rn)
02242 {
02243 reinsertnum = rn;
02244 assert(pageminfill + reinsertnum <= pagesize);
02245 }
02246
02248 void insertRect(const DataRef newdata)
02249 {
02250 assert(DTCallback->getMBR(newdata).valid());
02251
02252 NodeHead *root = pageman.getPage(rootpage);
02253
02254
02255 std::stack<pageid_t> path;
02256
02257 path.push(rootpage);
02258 class NodeHead *_leaf;
02259 if (root->level == 0) {
02260 _leaf = static_cast<class LeafNode*>(root)->chooseSubtree(*this, DTCallback->getMBR(newdata), 0, path);
02261 }
02262 else {
02263 _leaf = static_cast<class InnerNode*>(root)->chooseSubtree(*this, DTCallback->getMBR(newdata), 0, path);
02264 }
02265
02266 assert(_leaf);
02267 assert(_leaf->level == 0);
02268 class LeafNode *leaf = static_cast<class LeafNode*>(_leaf);
02269
02270
02271 char *overflowedLevel = static_cast<char*>(alloca(levels+1));
02272 memset(overflowedLevel, 0, levels+1);
02273
02274 pageid_t leafpage = path.top();
02275 path.pop();
02276 leaf->insertChild(*this, leafpage, LeafNodeData(newdata), path, overflowedLevel);
02277
02278 entries++;
02279 }
02280
02282 bool deleteRect(const DataRef rmdata)
02283 {
02284 assert(DTCallback->getMBR(rmdata).valid());
02285 NodeHead *root = pageman.getPage(rootpage);
02286
02287
02288 std::queue<pageid_t> path;
02289
02290 class LeafNode *leaf;
02291 if (root->level == 0) {
02292 leaf = static_cast<class LeafNode*>(root)->findLeaf(*this, LeafNodeData(rmdata), path);
02293 }
02294 else {
02295 leaf = static_cast<class InnerNode*>(root)->findLeaf(*this, LeafNodeData(rmdata), path);
02296 }
02297
02298 path.push(rootpage);
02299
02300 if (!leaf) return false;
02301
02302 assert(leaf->level == 0);
02303
02304 pageid_t leafpage = path.front();
02305 path.pop();
02306
02307 leaf->deleteDataLeaf(*this, leafpage, rmdata, path);
02308
02309 entries--;
02310
02311 return true;
02312 }
02313
02315 void writeFig(bool writefigheader, std::ostream &o, int maxlevel) const
02316 {
02317 if (writefigheader)
02318 o << "#FIG 3.2\nPortrait\nCenter\nMetric\nA0\n100.00\nSingle\n-2\n10000 2\n";
02319
02320
02321
02322 o << "0 32 #9E9E9E" << std::endl;
02323 o << "0 33 #7CF22D" << std::endl;
02324 o << "0 34 #1757C6" << std::endl;
02325 o << "0 35 #F00000" << std::endl;
02326 o << "0 36 #AD14AD" << std::endl;
02327
02328 NodeHead *root = pageman.getPage(rootpage);
02329
02330 #ifdef MOVIEMAKING
02331 Rect rect = root->nodeMBR;
02332
02333 rect = Rect(602460, -5483624, 1500876, -4751257);
02334
02335
02336 o << "2 2 0 1 " << 32 + root->level + 1 << " 7 " << 100 - root->level << " -1 -1 0.000 0 0 -1 0 0 5\n"
02337 << " "
02338 << rect.x1 << " " << rect.y1 << " "
02339 << rect.x2 << " " << rect.y1 << " "
02340 << rect.x2 << " " << rect.y2 << " "
02341 << rect.x1 << " " << rect.y2 << " "
02342 << rect.x1 << " " << rect.y1 << "\n";
02343 #endif
02344
02345 if (root->level == 0)
02346 static_cast<LeafNode*>(root)->writeFig(*this, o, maxlevel);
02347 else
02348 static_cast<InnerNode*>(root)->writeFig(*this, o, maxlevel);
02349 }
02350
02352 void saveSnapshot(std::ostream &s) const
02353 {
02354
02355 unsigned int key = 0x34343434;
02356 s.write(reinterpret_cast<char*>(&key), sizeof(key));
02357
02358
02359 key = pagesize;
02360 s.write(reinterpret_cast<const char*>(&key), sizeof(key));
02361
02362 key = sizeof(pageid_t);
02363 s.write(reinterpret_cast<const char*>(&key), sizeof(key));
02364
02365 key = sizeof(DataType);
02366 s.write(reinterpret_cast<const char*>(&key), sizeof(key));
02367
02368 key = sizeof(class InnerNode);
02369 s.write(reinterpret_cast<const char*>(&key), sizeof(key));
02370
02371 key = sizeof(class LeafNode);
02372 s.write(reinterpret_cast<const char*>(&key), sizeof(key));
02373
02374
02375 s.write(reinterpret_cast<const char*>(&rootpage), sizeof(rootpage));
02376
02377 s.write(reinterpret_cast<const char*>(&levels), sizeof(levels));
02378
02379 s.write(reinterpret_cast<const char*>(&entries), sizeof(entries));
02380
02381
02382
02383 key = pageman.innerpages.size();
02384 s.write(reinterpret_cast<const char*>(&key), sizeof(key));
02385
02386 for(unsigned int i = 0; i < pageman.innerpages.size(); i++)
02387 {
02388 if (pageman.innerpages[i] == NULL) continue;
02389
02390 key = i;
02391 s.write(reinterpret_cast<const char*>(&key), sizeof(key));
02392
02393 s.write(reinterpret_cast<const char*>(pageman.innerpages[i]), sizeof(InnerNode));
02394 }
02395
02396
02397 key = pageman.leafpages.size();
02398 s.write(reinterpret_cast<const char*>(&key), sizeof(key));
02399
02400 for(unsigned int i = 0; i < pageman.leafpages.size(); i++)
02401 {
02402 if (pageman.leafpages[i] == NULL) continue;
02403
02404 key = i;
02405 s.write(reinterpret_cast<const char*>(&key), sizeof(key));
02406
02407 s.write(reinterpret_cast<const char*>(pageman.leafpages[i]), sizeof(LeafNode));
02408 }
02409 }
02410
02412 bool loadSnapshot(std::istream &s)
02413 {
02414 unsigned int key;
02415
02416
02417 if (!s.read(reinterpret_cast<char*>(&key), sizeof(key))) return false;
02418 if (key != 0x34343434) return false;
02419
02420
02421 if (!s.read(reinterpret_cast<char*>(&key), sizeof(key))) return false;
02422 if (key != pagesize) return false;
02423
02424 if (!s.read(reinterpret_cast<char*>(&key), sizeof(key))) return false;
02425 if (key != sizeof(pageid_t)) return false;
02426
02427 if (!s.read(reinterpret_cast<char*>(&key), sizeof(key))) return false;
02428 if (key != sizeof(DataType)) return false;
02429
02430 if (!s.read(reinterpret_cast<char*>(&key), sizeof(key))) return false;
02431 if (key != sizeof(class InnerNode)) return false;
02432
02433 if (!s.read(reinterpret_cast<char*>(&key), sizeof(key))) return false;
02434 if (key != sizeof(class LeafNode)) return false;
02435
02436
02437 clear();
02438
02439
02440
02441 if (!s.read(reinterpret_cast<char*>(&rootpage), sizeof(rootpage))) return false;
02442
02443 if (!s.read(reinterpret_cast<char*>(&levels), sizeof(levels))) return false;
02444
02445 if (!s.read(reinterpret_cast<char*>(&entries), sizeof(entries))) return false;
02446
02447 std::cerr << "Loading R-Tree with " << entries << " entries: ";
02448
02449
02450 unsigned int len;
02451
02452 if (!s.read(reinterpret_cast<char*>(&len), sizeof(len))) return false;
02453 pageman.innerpages.resize(len);
02454
02455 for(unsigned int i = 0; i < len; i++)
02456 {
02457 if (!s.read(reinterpret_cast<char*>(&key), sizeof(key))) return false;
02458 if (key >= len) return false;
02459
02460 pageman.innerpages[key] = new InnerNode;
02461 if (!s.read(reinterpret_cast<char*>(pageman.innerpages[key]), sizeof(InnerNode))) return false;
02462 }
02463
02464 std::cerr << len << " inner nodes and ";
02465
02466
02467 if (!s.read(reinterpret_cast<char*>(&len), sizeof(len))) return false;
02468 pageman.leafpages.resize(len);
02469
02470 for(unsigned int i = 0; i < len; i++)
02471 {
02472 if (!s.read(reinterpret_cast<char*>(&key), sizeof(key))) return false;
02473 if (key >= len) return false;
02474
02475 pageman.leafpages[key] = new LeafNode;
02476 if (!s.read(reinterpret_cast<char*>(pageman.leafpages[key]), sizeof(LeafNode))) return false;
02477 }
02478
02479 std::cerr << len << " leaf nodes.\n";
02480
02481 return true;
02482 }
02483
02485 bool testTree() const
02486 {
02487 NodeHead *root = pageman.getPage(rootpage);
02488
02489 unsigned int testentries = 0;
02490
02491 if (root->level == 0) {
02492 return static_cast<class LeafNode*>(root)->checkNode(*this, levels, &testentries);
02493 }
02494 else {
02495 return static_cast<class InnerNode*>(root)->checkNode(*this, levels, &testentries);
02496 }
02497
02498 assert(testentries == entries);
02499 }
02500
02502 void calcStats(Stats &s) const
02503 {
02504 NodeHead *root = pageman.getPage(rootpage);
02505
02506 if (s.level.size() <= levels) {
02507 s.level.resize(levels+1);
02508 }
02509
02510 if (root->level == 0) {
02511 static_cast<class LeafNode*>(root)->calcStats(*this, s);
02512 }
02513 else {
02514 static_cast<class InnerNode*>(root)->calcStats(*this, s);
02515 }
02516 }
02518 AreaType calcOverlap() const
02519 {
02520 NodeHead *root = pageman.getPage(rootpage);
02521
02522 if (root->level == 0) {
02523 return static_cast<class LeafNode*>(root)->calcOverlap(*this);
02524 }
02525 else {
02526 return static_cast<class InnerNode*>(root)->calcOverlap(*this);
02527 }
02528 }
02529
02531 AreaType calcWasteArea() const
02532 {
02533 NodeHead *root = pageman.getPage(rootpage);
02534
02535 if (root->level == 0) {
02536 return static_cast<class LeafNode*>(root)->calcWasteArea(*this);
02537 }
02538 else {
02539 return static_cast<class InnerNode*>(root)->calcWasteArea(*this);
02540 }
02541 }
02542
02544 unsigned int size() const
02545 { return entries; }
02546
02548 bool empty() const
02549 { return (entries == 0); }
02550
02553 template <typename Visitor>
02554 void queryRange(const Rect &range, Visitor &vis) const
02555 {
02556 assert(range.valid());
02557
02558 std::stack<pageid_t> pagestack;
02559 pagestack.push(rootpage);
02560
02561 while(!pagestack.empty())
02562 {
02563 pageid_t page = pagestack.top();
02564 pagestack.pop();
02565
02566 NodeHead *node = pageman.getPage(page);
02567
02568 if (node->level == 0)
02569 {
02570 LeafNode *leaf = static_cast<LeafNode*>(node);
02571
02572 for(unsigned int ci = 0; ci < leaf->childnum; ci++)
02573 {
02574 if (leaf->children[ci].getMBR(*this).intersectsRect(range))
02575 {
02576 if (!vis(static_cast<const Rect&>(leaf->children[ci].getMBR(*this)),
02577 static_cast<DataType&>(leaf->children[ci])))
02578 return;
02579 }
02580 }
02581 }
02582 else
02583 {
02584 InnerNode *inner = static_cast<InnerNode*>(node);
02585
02586 for(unsigned int ci = 0; ci < inner->childnum; ci++)
02587 {
02588 if (inner->children[ci].getMBR(*this).intersectsRect(range))
02589 {
02590 pagestack.push(inner->children[ci].page);
02591 }
02592 }
02593 }
02594 }
02595 }
02596
02599 class NNPQData
02600 {
02601 public:
02602 pageid_t page;
02603
02604 AreaType mindist;
02605
02606 NNPQData(pageid_t _page, AreaType _mindist)
02607 : page(_page), mindist(_mindist)
02608 {
02609 }
02610
02611 bool operator< (const class NNPQData &o) const
02612 { return mindist < o.mindist; }
02613 };
02614
02615
02616
02617
02620 template <typename NNVisitor>
02621 void queryNearestNeighbor(const Point &point, NNVisitor &vis) const
02622 {
02623
02624
02625
02626
02627 std::priority_queue<NNPQData, std::deque<NNPQData> > rectqueue;
02628
02629 rectqueue.push(NNPQData(rootpage, 0));
02630
02631 while(!rectqueue.empty())
02632 {
02633 NNPQData rp = rectqueue.top();
02634
02635
02636
02637 if (rp.mindist >= vis.mindistance) break;
02638
02639 rectqueue.pop();
02640
02641
02642 NodeHead *node = pageman.getPage(rp.page);
02643
02644 if (node->level == 0)
02645 {
02646 LeafNode *leaf = static_cast<LeafNode*>(node);
02647
02648 for(unsigned int ci = 0; ci < leaf->childnum; ci++)
02649 {
02650 AreaType md = point.getMinimumDistanceSquare(leaf->children[ci].getMBR(*this));
02651
02652 if (md <= vis.mindistance)
02653 {
02654 if (!vis(static_cast<const Rect&>(leaf->children[ci].getMBR(*this)),
02655 md,
02656 static_cast<DataType&>(leaf->children[ci])))
02657 return;
02658 }
02659 }
02660 }
02661 else
02662 {
02663 InnerNode *inner = static_cast<InnerNode*>(node);
02664
02665 for(unsigned int ci = 0; ci < inner->childnum; ci++)
02666 {
02667
02668 AreaType md = point.getMinimumDistanceSquare(inner->children[ci].getMBR(*this));
02669
02670 if (md <= vis.mindistance)
02671 rectqueue.push( NNPQData(inner->children[ci].page, md) );
02672 }
02673 }
02674
02675 }
02676 }
02677 };
02678 };
02679
02681 inline std::ostream& operator<< (std::ostream &o, const RTree::LevelStats &ls)
02682 {
02683 return o << "nodes: " << ls.nodes << ", "
02684 << "children: " << ls.children << ", "
02685 << "unused: " << ls.unusedchildren << ", "
02686 << "avgfill: " << (static_cast<double>(ls.children) / ls.nodes) << ", "
02687 << "bytes: " << ls.bytes << ", "
02688 << "unused: " << ls.unusedbytes << ", "
02689 << "overlap: " << ls.overlap << ", "
02690 << "wastearea: " << ls.wastearea;
02691 }
02692
02694 inline RTree::LevelStats operator+ (const RTree::LevelStats &a, const RTree::LevelStats &b)
02695 {
02696 RTree::LevelStats c;
02697
02698 c += a;
02699 c += b;
02700
02701 return c;
02702 }
02703
02704 }
02705
02706 #endif // VGS_RTree_H