[GRASS-dev] vector large file support

Glynn Clements glynn at gclements.plus.com
Tue Feb 17 18:15:47 EST 2009


Markus Metz wrote:

> >> That thing branch[i].child is a pointer to the next node in the tree, if 
> >> I understand the code correctly.
> >>     
> >
> > It's either a pointer to the child or, at the lowest level (where
> > there are no children), an integer ("tid").
> 
> Hmmm. What when RTreeInsertRect() is called by RTreeDeleteRect() during 
> reinsertion? For internal nodes, tmp_nptr->b.child was a pointer to a 
> node, but now it is cast to an integer, and this integer gets stuffed 
> back into tmp_nptr->b.child?

It took me a while, but I think I understand. Some of the functions
use an "int tid" parameter for an arbitrary child, which could be
either an integer tid (level == 0) or a pointer to a child node
(level > 0).

AFAICT, the code always passes the correct type of value for the
level, but a 64-bit pointer passed via an integer parameter will get
truncated.

External callers aren't a problem, as they only ever call
RTreeInsertRect() with level == 0. It's only when RTreeDeleteRect()
uses it to re-insert internal nodes that the truncation can arise.

> To me it seems that the solution interfering the least with the current 
> code would be to make use of off_t (only some replacements of int with 
> off_t) and adjust the Makefile for rtree accordingly. Somehow this 
> appears to me more dangerous than my solution with an additional int id, 
> but I can't give precise reasons why. Maybe because higher-level code 
> would have to be adjusted too, at least everything using a 
> SearchHitCallback with RTreeSearch().
> As I said, I understand the concept better than the code. At least, I 
> think that passing around pointer addresses as integer is not good 
> coding practise.

I'm not happy with using off_t, as I'm not convinced that it will
always be large enough to hold a pointer.

My inclination would be to change the "int tid" parameters to
"struct Node *child", and make RTreeInsertRect() a compatibility
wrapper for the benefit of external callers, i.e.:

-static int RTreeInsertRect2(struct Rect *r, int tid, ...
+static int RTreeInsertRect2(struct Rect *r, struct Node *child, ...

-int RTreeInsertRect(struct Rect *R, int Tid, ...
+int RTreeInsertRect1(struct Rect *R, struct Node *child, ...

int RTreeInsertRect(struct Rect *R, int Tid, struct Node **Root, int Level)
{
	assert(level == 0);
	return RTreeInsertRect1(R, (struct Node *) Tid, Root, Level);
}

I don't think the problems go any further than that.

If the code was actually putting an pointer into a level==0 node or an
integer into a level>0 node, we would have run into this long before
now.

-- 
Glynn Clements <glynn at gclements.plus.com>


More information about the grass-dev mailing list