[postgis-devel] getPoint2d_p

strk strk at keybit.net
Sat Dec 13 16:34:39 PST 2008


On Sat, Dec 13, 2008 at 04:19:42PM -0800, Paul Ramsey wrote:
> I'm looking at the simple distance calculating function, and I see this:
> 
> double lwgeom_pointarray_length2d(POINTARRAY *pts)
> {
>         double dist = 0.0;
>         int i;
>         POINT2D frm;
>         POINT2D to;
> 
>         if ( pts->npoints < 2 ) return 0.0;
>         for (i=0; i<pts->npoints-1;i++)
>         {
>                 getPoint2d_p(pts, i, &frm);
>                 getPoint2d_p(pts, i+1, &to);
>                 dist += sqrt( ( (frm.x - to.x)*(frm.x - to.x) )  +
>                                 ((frm.y - to.y)*(frm.y - to.y) ) );
>         }
>         return dist;
> }
> 
> That's simple enough... but what burns me is that getPoint2d_p does this:
> 
> int
> getPoint2d_p(const POINTARRAY *pa, int n, POINT2D *point)
> {
>         memcpy(point, getPoint_internal(pa, n), sizeof(POINT2D));
>         return 1;
> }
> 
> We're just reading, why the memcpy? Sure, it's pretty darn fast, hand
> optimized assembler by the gods of gcc and all that, but surely it
> would nicer to just get a pointer into a structure.
> 
> All this derives from having our point arrays stored in "uchar
> *serialized_pointlist" the primary advantage being ... ? 

Using what postgresql gives us IIRC.
IE: tipically our POINTARRAY is just some bytes into what we get out of
PG_DETOAST_DATUM, if we force interpretation of it as a double*, 
memory alignemtn constraints of the hosting machine may disagree.

On some machines a double* can't be at arbitrary memory locations, but
only at addresses which are multiples of sizeo(double). So if you take this
layout:

  X      XXXXXXX XXXXXXXX XXXXXX
 header  point1  point2   point3

your points are not aligned to 'double' boundary.

The layout was an example, see the internal representation of GEOMETRY
type for a more accurate layout.

--strk;



More information about the postgis-devel mailing list