[geos-commits] r2415 - in trunk/source: headers/geos/index/quadtree
index/quadtree
svn_geos at osgeo.org
svn_geos at osgeo.org
Mon Apr 27 15:38:45 EDT 2009
Author: strk
Date: 2009-04-27 15:38:44 -0400 (Mon, 27 Apr 2009)
New Revision: 2415
Modified:
trunk/source/headers/geos/index/quadtree/Node.h
trunk/source/headers/geos/index/quadtree/Root.h
trunk/source/index/quadtree/Node.cpp
trunk/source/index/quadtree/Root.cpp
Log:
Refactor signatures to make ownership transfers more explicit. Fixed another leak in Node::insertNode.
Modified: trunk/source/headers/geos/index/quadtree/Node.h
===================================================================
--- trunk/source/headers/geos/index/quadtree/Node.h 2009-04-27 19:22:07 UTC (rev 2414)
+++ trunk/source/headers/geos/index/quadtree/Node.h 2009-04-27 19:38:44 UTC (rev 2415)
@@ -52,15 +52,21 @@
private:
/// Owned by this class
- geom::Envelope *env;
+ std::auto_ptr<geom::Envelope> env;
geom::Coordinate centre;
int level;
+ /**
+ * Get the subquad for the index.
+ * If it doesn't exist, create it.
+ *
+ * Ownership of the returned object belongs to this class.
+ */
Node* getSubnode(int index);
- Node* createSubnode(int index);
+ std::auto_ptr<Node> createSubnode(int index);
protected:
@@ -70,26 +76,31 @@
public:
+ // Create a node computing level from given envelope
static std::auto_ptr<Node> createNode(const geom::Envelope& env);
- static std::auto_ptr<Node> createExpanded(Node *node,
- const geom::Envelope *addEnv);
+ /// Create a node containing the given node and envelope
+ //
+ /// @param node if not null, will be inserted to the returned node
+ /// @param addEnv minimum envelope to use for the node
+ ///
+ static std::auto_ptr<Node> createExpanded(std::auto_ptr<Node> node,
+ const geom::Envelope& addEnv);
- // Takes ownership of envelope
- Node(geom::Envelope *nenv, int nlevel)
+ Node(std::auto_ptr<geom::Envelope> nenv, int nlevel)
:
env(nenv),
- centre((nenv->getMinX()+nenv->getMaxX())/2,
- (nenv->getMinY()+nenv->getMaxY())/2),
+ centre((env->getMinX()+env->getMaxX())/2,
+ (env->getMinY()+env->getMaxY())/2),
level(nlevel)
{
}
- virtual ~Node() { delete env; }
+ virtual ~Node() {}
/// Return Envelope associated with this node
/// ownership retained by this object
- geom::Envelope* getEnvelope() { return env; }
+ geom::Envelope* getEnvelope() { return env.get(); }
/** \brief
* Returns the subquad containing the envelope.
@@ -104,7 +115,7 @@
*/
NodeBase* find(const geom::Envelope *searchEnv);
- void insertNode(Node *node);
+ void insertNode(std::auto_ptr<Node> node);
std::string toString() const;
Modified: trunk/source/headers/geos/index/quadtree/Root.h
===================================================================
--- trunk/source/headers/geos/index/quadtree/Root.h 2009-04-27 19:22:07 UTC (rev 2414)
+++ trunk/source/headers/geos/index/quadtree/Root.h 2009-04-27 19:38:44 UTC (rev 2415)
@@ -51,14 +51,15 @@
private:
- static geom::Coordinate origin;
+ static const geom::Coordinate origin;
/**
* insert an item which is known to be contained in the tree rooted at
* the given QuadNode root. Lower levels of the tree will be created
* if necessary to hold the item.
*/
- void insertContained(Node *tree, const geom::Envelope *itemEnv, void* item);
+ void insertContained(Node *tree, const geom::Envelope *itemEnv,
+ void* item);
public:
Modified: trunk/source/index/quadtree/Node.cpp
===================================================================
--- trunk/source/index/quadtree/Node.cpp 2009-04-27 19:22:07 UTC (rev 2414)
+++ trunk/source/index/quadtree/Node.cpp 2009-04-27 19:38:44 UTC (rev 2415)
@@ -46,24 +46,34 @@
Node::createNode(const Envelope& env)
{
Key key(env);
+
+ std::auto_ptr<Envelope> nenv ( new Envelope(key.getEnvelope()) );
std::auto_ptr<Node> node (
- new Node(new Envelope(key.getEnvelope()),
- key.getLevel())
+ new Node(nenv, key.getLevel())
);
return node;
}
/* static public */
std::auto_ptr<Node>
-Node::createExpanded(Node *node, const Envelope *addEnv)
+Node::createExpanded(std::auto_ptr<Node> node, const Envelope& addEnv)
{
- Envelope expandEnv(*addEnv);
- if (node!=NULL) expandEnv.expandToInclude(node->env);
+ Envelope expandEnv(addEnv);
+ if ( node.get() ) // should this be asserted ?
+ {
+ expandEnv.expandToInclude(node->getEnvelope());
+ }
+
#if GEOS_DEBUG
cerr<<"Node::createExpanded computed "<<expandEnv.toString()<<endl;
#endif
+
std::auto_ptr<Node> largerNode = createNode(expandEnv);
- if (node!=NULL) largerNode->insertNode(node);
+ if ( node.get() ) // should this be asserted ?
+ {
+ largerNode->insertNode(node);
+ }
+
return largerNode;
}
@@ -71,14 +81,17 @@
Node*
Node::getNode(const Envelope *searchEnv)
{
- int subnodeIndex=getSubnodeIndex(searchEnv, centre);
+ int subnodeIndex = getSubnodeIndex(searchEnv, centre);
// if subquadIndex is -1 searchEnv is not contained in a subquad
- if (subnodeIndex!=-1) {
+ if (subnodeIndex != -1)
+ {
// create the quad if it does not exist
- Node *node=getSubnode(subnodeIndex);
+ Node *node = getSubnode(subnodeIndex);
// recursively search the found/created quad
return node->getNode(searchEnv);
- } else {
+ }
+ else
+ {
return this;
}
}
@@ -99,36 +112,50 @@
return this;
}
-void Node::insertNode(Node* node) {
- assert(env==NULL || env->contains(node->env));
- //System.out.println(env);
- //System.out.println(quad.env);
- int index=getSubnodeIndex(node->env, centre);
- //System.out.println(index);
- if (node->level==level-1) {
- subnode[index]=node;
+void
+Node::insertNode(std::auto_ptr<Node> node)
+{
+ assert( env->contains(node->getEnvelope()) );
+
+ int index = getSubnodeIndex(node->getEnvelope(), centre);
+
+ if (node->level == level-1)
+ {
+ // We take ownership of node
+ delete subnode[index];
+ subnode[index] = node.release();
+
//System.out.println("inserted");
- } else {
- // the quad is not a direct child, so make a new child quad to contain it
- // and recursively insert the quad
- Node *childNode=createSubnode(index);
+ }
+ else
+ {
+ // the quad is not a direct child, so make a new child
+ // quad to contain it and recursively insert the quad
+ std::auto_ptr<Node> childNode ( createSubnode(index) );
+
+ // childNode takes ownership of node
childNode->insertNode(node);
- subnode[index]=childNode;
+
+ // We take ownership of childNode
+ delete subnode[index];
+ subnode[index] = childNode.release();
}
}
-/**
-* get the subquad for the index.
-* If it doesn't exist, create it
-*/
-Node* Node::getSubnode(int index){
- if (subnode[index]==NULL) {
- subnode[index]=createSubnode(index);
+Node*
+Node::getSubnode(int index)
+{
+ assert(index >=0 && index < 4);
+ if (subnode[index] == NULL)
+ {
+ subnode[index] = createSubnode(index).release();
}
return subnode[index];
}
-Node* Node::createSubnode(int index) {
+std::auto_ptr<Node>
+Node::createSubnode(int index)
+{
// create a new subquad in the appropriate quadrant
double minx=0.0;
double maxx=0.0;
@@ -148,21 +175,21 @@
miny=env->getMinY();
maxy=centre.y;
break;
- case 2:
+ case 2:
minx=env->getMinX();
maxx=centre.x;
miny=centre.y;
maxy=env->getMaxY();
break;
- case 3:
+ case 3:
minx=centre.x;
maxx=env->getMaxX();
miny=centre.y;
maxy=env->getMaxY();
break;
}
- Envelope *sqEnv=new Envelope(minx,maxx,miny,maxy);
- Node *node=new Node(sqEnv,level-1);
+ std::auto_ptr<Envelope> sqEnv ( new Envelope(minx,maxx,miny,maxy) );
+ std::auto_ptr<Node> node ( new Node(sqEnv, level-1) );
return node;
}
@@ -175,6 +202,7 @@
return os.str();
}
+
} // namespace geos.index.quadtree
} // namespace geos.index
} // namespace geos
Modified: trunk/source/index/quadtree/Root.cpp
===================================================================
--- trunk/source/index/quadtree/Root.cpp 2009-04-27 19:22:07 UTC (rev 2414)
+++ trunk/source/index/quadtree/Root.cpp 2009-04-27 19:38:44 UTC (rev 2415)
@@ -42,7 +42,7 @@
// the singleton root quad is centred at the origin.
//Coordinate* Root::origin=new Coordinate(0.0, 0.0);
-Coordinate Root::origin(0.0, 0.0);
+const Coordinate Root::origin(0.0, 0.0);
/*public*/
void
@@ -50,11 +50,12 @@
{
#if GEOS_DEBUG
- std::cerr<<"("<<this<<") insert("<<itemEnv->toString()<<", "<<item<<") called"<<std::endl;
+ std::cerr<< "Root("<<this<<")::insert("<<itemEnv->toString()<<", "<<item<<") called"<<std::endl;
#endif
- int index=getSubnodeIndex(itemEnv,origin);
+ int index = getSubnodeIndex(itemEnv, origin);
// if index is -1, itemEnv must cross the X or Y axis.
- if (index==-1) {
+ if (index==-1)
+ {
#if GEOS_DEBUG
std::cerr<<" -1 subnode index"<<std::endl;
#endif
@@ -66,7 +67,7 @@
* the item must be contained in one quadrant, so insert it into the
* tree for that quadrant (which may not yet exist)
*/
- Node *node=subnode[index];
+ Node *node = subnode[index];
#if GEOS_DEBUG
std::cerr<<"("<<this<<") subnode["<<index<<"] @ "<<node<<std::endl;
@@ -76,20 +77,36 @@
* If the subquad doesn't exist or this item is not contained in it,
* have to expand the tree upward to contain the item.
*/
- if (node==NULL || !node->getEnvelope()->contains(itemEnv)) {
- std::auto_ptr<Node> largerNode = Node::createExpanded(node,
- itemEnv);
- //delete subnode[index];
- // TODO: should subnode[] be an array of auto_ptrs ?
- subnode[index]=largerNode.release();
+ if (node==NULL || !node->getEnvelope()->contains(itemEnv))
+ {
+ std::auto_ptr<Node> snode (node); // may be NULL
+ node = 0; subnode[index] = 0;
+
+ std::auto_ptr<Node> largerNode =
+ Node::createExpanded(snode, *itemEnv);
+
+#if GEOS_DEBUG
+ std::cerr<<"("<<this<<") created expanded node " << largerNode.get() << " containing previously reported subnode" << std::endl;
+#endif
+
+ // Previous subnode was passed as a child of the larger one
+ assert(!subnode[index]);
+ subnode[index] = largerNode.release();
}
+#if GEOS_DEBUG
+ std::cerr<<"("<<this<<") calling insertContained with subnode " << subnode[index] << std::endl;
+#endif
/*
* At this point we have a subquad which exists and must contain
* contains the env for the item. Insert the item into the tree.
*/
- insertContained(subnode[index],itemEnv,item);
+ insertContained(subnode[index], itemEnv, item);
+#if GEOS_DEBUG
+ std::cerr<<"("<<this<<") done calling insertContained with subnode " << subnode[index] << std::endl;
+#endif
+
//System.out.println("depth = " + root.depth() + " size = " + root.size());
//System.out.println(" size = " + size());
}
@@ -113,9 +130,13 @@
NodeBase *node;
if (isZeroX || isZeroY)
- node=tree->find(itemEnv);
+ {
+ node = tree->find(itemEnv);
+ }
else
- node=tree->getNode(itemEnv);
+ {
+ node = tree->getNode(itemEnv);
+ }
node->add(item);
}
More information about the geos-commits
mailing list