rtree.c

Go to the documentation of this file.
00001 /*
00002 ** 2001 September 15
00003 **
00004 ** The author disclaims copyright to this source code.  In place of
00005 ** a legal notice, here is a blessing:
00006 **
00007 **    May you do good and not evil.
00008 **    May you find forgiveness for yourself and forgive others.
00009 **    May you share freely, never taking more than you give.
00010 **
00011 *************************************************************************
00012 ** This file contains code for implementations of the r-tree and r*-tree
00013 ** algorithms packaged as an SQLite virtual table module.
00014 **
00015 ** $Id: rtree.c,v 1.11 2008/11/12 15:24:27 drh Exp $
00016 */
00017 
00018 #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RTREE)
00019 
00020 /*
00021 ** This file contains an implementation of a couple of different variants
00022 ** of the r-tree algorithm. See the README file for further details. The 
00023 ** same data-structure is used for all, but the algorithms for insert and
00024 ** delete operations vary. The variants used are selected at compile time 
00025 ** by defining the following symbols:
00026 */
00027 
00028 /* Either, both or none of the following may be set to activate 
00029 ** r*tree variant algorithms.
00030 */
00031 #define VARIANT_RSTARTREE_CHOOSESUBTREE 0
00032 #define VARIANT_RSTARTREE_REINSERT      1
00033 
00034 /* 
00035 ** Exactly one of the following must be set to 1.
00036 */
00037 #define VARIANT_GUTTMAN_QUADRATIC_SPLIT 0
00038 #define VARIANT_GUTTMAN_LINEAR_SPLIT    0
00039 #define VARIANT_RSTARTREE_SPLIT         1
00040 
00041 #define VARIANT_GUTTMAN_SPLIT \
00042         (VARIANT_GUTTMAN_LINEAR_SPLIT||VARIANT_GUTTMAN_QUADRATIC_SPLIT)
00043 
00044 #if VARIANT_GUTTMAN_QUADRATIC_SPLIT
00045   #define PickNext QuadraticPickNext
00046   #define PickSeeds QuadraticPickSeeds
00047   #define AssignCells splitNodeGuttman
00048 #endif
00049 #if VARIANT_GUTTMAN_LINEAR_SPLIT
00050   #define PickNext LinearPickNext
00051   #define PickSeeds LinearPickSeeds
00052   #define AssignCells splitNodeGuttman
00053 #endif
00054 #if VARIANT_RSTARTREE_SPLIT
00055   #define AssignCells splitNodeStartree
00056 #endif
00057 
00058 
00059 #ifndef SQLITE_CORE
00060   #include "sqlite3ext.h"
00061   SQLITE_EXTENSION_INIT1
00062 #else
00063   #include "sqlite3.h"
00064 #endif
00065 
00066 #include <string.h>
00067 #include <assert.h>
00068 
00069 #ifndef SQLITE_AMALGAMATION
00070 typedef sqlite3_int64 i64;
00071 typedef unsigned char u8;
00072 typedef unsigned int u32;
00073 #endif
00074 
00075 typedef struct Rtree Rtree;
00076 typedef struct RtreeCursor RtreeCursor;
00077 typedef struct RtreeNode RtreeNode;
00078 typedef struct RtreeCell RtreeCell;
00079 typedef struct RtreeConstraint RtreeConstraint;
00080 typedef union RtreeCoord RtreeCoord;
00081 
00082 /* The rtree may have between 1 and RTREE_MAX_DIMENSIONS dimensions. */
00083 #define RTREE_MAX_DIMENSIONS 5
00084 
00085 /* Size of hash table Rtree.aHash. This hash table is not expected to
00086 ** ever contain very many entries, so a fixed number of buckets is 
00087 ** used.
00088 */
00089 #define HASHSIZE 128
00090 
00091 /* 
00092 ** An rtree virtual-table object.
00093 */
00094 struct Rtree {
00095   sqlite3_vtab base;
00096   sqlite3 *db;                /* Host database connection */
00097   int iNodeSize;              /* Size in bytes of each node in the node table */
00098   int nDim;                   /* Number of dimensions */
00099   int nBytesPerCell;          /* Bytes consumed per cell */
00100   int iDepth;                 /* Current depth of the r-tree structure */
00101   char *zDb;                  /* Name of database containing r-tree table */
00102   char *zName;                /* Name of r-tree table */ 
00103   RtreeNode *aHash[HASHSIZE]; /* Hash table of in-memory nodes. */ 
00104   int nBusy;                  /* Current number of users of this structure */
00105 
00106   /* List of nodes removed during a CondenseTree operation. List is
00107   ** linked together via the pointer normally used for hash chains -
00108   ** RtreeNode.pNext. RtreeNode.iNode stores the depth of the sub-tree 
00109   ** headed by the node (leaf nodes have RtreeNode.iNode==0).
00110   */
00111   RtreeNode *pDeleted;
00112   int iReinsertHeight;        /* Height of sub-trees Reinsert() has run on */
00113 
00114   /* Statements to read/write/delete a record from xxx_node */
00115   sqlite3_stmt *pReadNode;
00116   sqlite3_stmt *pWriteNode;
00117   sqlite3_stmt *pDeleteNode;
00118 
00119   /* Statements to read/write/delete a record from xxx_rowid */
00120   sqlite3_stmt *pReadRowid;
00121   sqlite3_stmt *pWriteRowid;
00122   sqlite3_stmt *pDeleteRowid;
00123 
00124   /* Statements to read/write/delete a record from xxx_parent */
00125   sqlite3_stmt *pReadParent;
00126   sqlite3_stmt *pWriteParent;
00127   sqlite3_stmt *pDeleteParent;
00128 
00129   int eCoordType;
00130 };
00131 
00132 /* Possible values for eCoordType: */
00133 #define RTREE_COORD_REAL32 0
00134 #define RTREE_COORD_INT32  1
00135 
00136 /*
00137 ** The minimum number of cells allowed for a node is a third of the 
00138 ** maximum. In Gutman's notation:
00139 **
00140 **     m = M/3
00141 **
00142 ** If an R*-tree "Reinsert" operation is required, the same number of
00143 ** cells are removed from the overfull node and reinserted into the tree.
00144 */
00145 #define RTREE_MINCELLS(p) ((((p)->iNodeSize-4)/(p)->nBytesPerCell)/3)
00146 #define RTREE_REINSERT(p) RTREE_MINCELLS(p)
00147 #define RTREE_MAXCELLS 51
00148 
00149 /* 
00150 ** An rtree cursor object.
00151 */
00152 struct RtreeCursor {
00153   sqlite3_vtab_cursor base;
00154   RtreeNode *pNode;                 /* Node cursor is currently pointing at */
00155   int iCell;                        /* Index of current cell in pNode */
00156   int iStrategy;                    /* Copy of idxNum search parameter */
00157   int nConstraint;                  /* Number of entries in aConstraint */
00158   RtreeConstraint *aConstraint;     /* Search constraints. */
00159 };
00160 
00161 union RtreeCoord {
00162   float f;
00163   int i;
00164 };
00165 
00166 /*
00167 ** The argument is an RtreeCoord. Return the value stored within the RtreeCoord
00168 ** formatted as a double. This macro assumes that local variable pRtree points
00169 ** to the Rtree structure associated with the RtreeCoord.
00170 */
00171 #define DCOORD(coord) (                           \
00172   (pRtree->eCoordType==RTREE_COORD_REAL32) ?      \
00173     ((double)coord.f) :                           \
00174     ((double)coord.i)                             \
00175 )
00176 
00177 /*
00178 ** A search constraint.
00179 */
00180 struct RtreeConstraint {
00181   int iCoord;                       /* Index of constrained coordinate */
00182   int op;                           /* Constraining operation */
00183   double rValue;                    /* Constraint value. */
00184 };
00185 
00186 /* Possible values for RtreeConstraint.op */
00187 #define RTREE_EQ 0x41
00188 #define RTREE_LE 0x42
00189 #define RTREE_LT 0x43
00190 #define RTREE_GE 0x44
00191 #define RTREE_GT 0x45
00192 
00193 /* 
00194 ** An rtree structure node.
00195 **
00196 ** Data format (RtreeNode.zData):
00197 **
00198 **   1. If the node is the root node (node 1), then the first 2 bytes
00199 **      of the node contain the tree depth as a big-endian integer.
00200 **      For non-root nodes, the first 2 bytes are left unused.
00201 **
00202 **   2. The next 2 bytes contain the number of entries currently 
00203 **      stored in the node.
00204 **
00205 **   3. The remainder of the node contains the node entries. Each entry
00206 **      consists of a single 8-byte integer followed by an even number
00207 **      of 4-byte coordinates. For leaf nodes the integer is the rowid
00208 **      of a record. For internal nodes it is the node number of a
00209 **      child page.
00210 */
00211 struct RtreeNode {
00212   RtreeNode *pParent;               /* Parent node */
00213   i64 iNode;
00214   int nRef;
00215   int isDirty;
00216   u8 *zData;
00217   RtreeNode *pNext;                 /* Next node in this hash chain */
00218 };
00219 #define NCELL(pNode) readInt16(&(pNode)->zData[2])
00220 
00221 /* 
00222 ** Structure to store a deserialized rtree record.
00223 */
00224 struct RtreeCell {
00225   i64 iRowid;
00226   RtreeCoord aCoord[RTREE_MAX_DIMENSIONS*2];
00227 };
00228 
00229 #ifndef MAX
00230 # define MAX(x,y) ((x) < (y) ? (y) : (x))
00231 #endif
00232 #ifndef MIN
00233 # define MIN(x,y) ((x) > (y) ? (y) : (x))
00234 #endif
00235 
00236 /*
00237 ** Functions to deserialize a 16 bit integer, 32 bit real number and
00238 ** 64 bit integer. The deserialized value is returned.
00239 */
00240 static int readInt16(u8 *p){
00241   return (p[0]<<8) + p[1];
00242 }
00243 static void readCoord(u8 *p, RtreeCoord *pCoord){
00244   u32 i = (
00245     (((u32)p[0]) << 24) + 
00246     (((u32)p[1]) << 16) + 
00247     (((u32)p[2]) <<  8) + 
00248     (((u32)p[3]) <<  0)
00249   );
00250   *(u32 *)pCoord = i;
00251 }
00252 static i64 readInt64(u8 *p){
00253   return (
00254     (((i64)p[0]) << 56) + 
00255     (((i64)p[1]) << 48) + 
00256     (((i64)p[2]) << 40) + 
00257     (((i64)p[3]) << 32) + 
00258     (((i64)p[4]) << 24) + 
00259     (((i64)p[5]) << 16) + 
00260     (((i64)p[6]) <<  8) + 
00261     (((i64)p[7]) <<  0)
00262   );
00263 }
00264 
00265 /*
00266 ** Functions to serialize a 16 bit integer, 32 bit real number and
00267 ** 64 bit integer. The value returned is the number of bytes written
00268 ** to the argument buffer (always 2, 4 and 8 respectively).
00269 */
00270 static int writeInt16(u8 *p, int i){
00271   p[0] = (i>> 8)&0xFF;
00272   p[1] = (i>> 0)&0xFF;
00273   return 2;
00274 }
00275 static int writeCoord(u8 *p, RtreeCoord *pCoord){
00276   u32 i;
00277   assert( sizeof(RtreeCoord)==4 );
00278   assert( sizeof(u32)==4 );
00279   i = *(u32 *)pCoord;
00280   p[0] = (i>>24)&0xFF;
00281   p[1] = (i>>16)&0xFF;
00282   p[2] = (i>> 8)&0xFF;
00283   p[3] = (i>> 0)&0xFF;
00284   return 4;
00285 }
00286 static int writeInt64(u8 *p, i64 i){
00287   p[0] = (i>>56)&0xFF;
00288   p[1] = (i>>48)&0xFF;
00289   p[2] = (i>>40)&0xFF;
00290   p[3] = (i>>32)&0xFF;
00291   p[4] = (i>>24)&0xFF;
00292   p[5] = (i>>16)&0xFF;
00293   p[6] = (i>> 8)&0xFF;
00294   p[7] = (i>> 0)&0xFF;
00295   return 8;
00296 }
00297 
00298 /*
00299 ** Increment the reference count of node p.
00300 */
00301 static void nodeReference(RtreeNode *p){
00302   if( p ){
00303     p->nRef++;
00304   }
00305 }
00306 
00307 /*
00308 ** Clear the content of node p (set all bytes to 0x00).
00309 */
00310 static void nodeZero(Rtree *pRtree, RtreeNode *p){
00311   if( p ){
00312     memset(&p->zData[2], 0, pRtree->iNodeSize-2);
00313     p->isDirty = 1;
00314   }
00315 }
00316 
00317 /*
00318 ** Given a node number iNode, return the corresponding key to use
00319 ** in the Rtree.aHash table.
00320 */
00321 static int nodeHash(i64 iNode){
00322   return (
00323     (iNode>>56) ^ (iNode>>48) ^ (iNode>>40) ^ (iNode>>32) ^ 
00324     (iNode>>24) ^ (iNode>>16) ^ (iNode>> 8) ^ (iNode>> 0)
00325   ) % HASHSIZE;
00326 }
00327 
00328 /*
00329 ** Search the node hash table for node iNode. If found, return a pointer
00330 ** to it. Otherwise, return 0.
00331 */
00332 static RtreeNode *nodeHashLookup(Rtree *pRtree, i64 iNode){
00333   RtreeNode *p;
00334   assert( iNode!=0 );
00335   for(p=pRtree->aHash[nodeHash(iNode)]; p && p->iNode!=iNode; p=p->pNext);
00336   return p;
00337 }
00338 
00339 /*
00340 ** Add node pNode to the node hash table.
00341 */
00342 static void nodeHashInsert(Rtree *pRtree, RtreeNode *pNode){
00343   if( pNode ){
00344     int iHash;
00345     assert( pNode->pNext==0 );
00346     iHash = nodeHash(pNode->iNode);
00347     pNode->pNext = pRtree->aHash[iHash];
00348     pRtree->aHash[iHash] = pNode;
00349   }
00350 }
00351 
00352 /*
00353 ** Remove node pNode from the node hash table.
00354 */
00355 static void nodeHashDelete(Rtree *pRtree, RtreeNode *pNode){
00356   RtreeNode **pp;
00357   if( pNode->iNode!=0 ){
00358     pp = &pRtree->aHash[nodeHash(pNode->iNode)];
00359     for( ; (*pp)!=pNode; pp = &(*pp)->pNext){ assert(*pp); }
00360     *pp = pNode->pNext;
00361     pNode->pNext = 0;
00362   }
00363 }
00364 
00365 /*
00366 ** Allocate and return new r-tree node. Initially, (RtreeNode.iNode==0),
00367 ** indicating that node has not yet been assigned a node number. It is
00368 ** assigned a node number when nodeWrite() is called to write the
00369 ** node contents out to the database.
00370 */
00371 static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent, int zero){
00372   RtreeNode *pNode;
00373   pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode) + pRtree->iNodeSize);
00374   if( pNode ){
00375     memset(pNode, 0, sizeof(RtreeNode) + (zero?pRtree->iNodeSize:0));
00376     pNode->zData = (u8 *)&pNode[1];
00377     pNode->nRef = 1;
00378     pNode->pParent = pParent;
00379     pNode->isDirty = 1;
00380     nodeReference(pParent);
00381   }
00382   return pNode;
00383 }
00384 
00385 /*
00386 ** Obtain a reference to an r-tree node.
00387 */
00388 static int
00389 nodeAcquire(
00390   Rtree *pRtree,             /* R-tree structure */
00391   i64 iNode,                 /* Node number to load */
00392   RtreeNode *pParent,        /* Either the parent node or NULL */
00393   RtreeNode **ppNode         /* OUT: Acquired node */
00394 ){
00395   int rc;
00396   RtreeNode *pNode;
00397 
00398   /* Check if the requested node is already in the hash table. If so,
00399   ** increase its reference count and return it.
00400   */
00401   if( (pNode = nodeHashLookup(pRtree, iNode)) ){
00402     assert( !pParent || !pNode->pParent || pNode->pParent==pParent );
00403     if( pParent ){
00404       pNode->pParent = pParent;
00405     }
00406     pNode->nRef++;
00407     *ppNode = pNode;
00408     return SQLITE_OK;
00409   }
00410 
00411   pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode) + pRtree->iNodeSize);
00412   if( !pNode ){
00413     *ppNode = 0;
00414     return SQLITE_NOMEM;
00415   }
00416   pNode->pParent = pParent;
00417   pNode->zData = (u8 *)&pNode[1];
00418   pNode->nRef = 1;
00419   pNode->iNode = iNode;
00420   pNode->isDirty = 0;
00421   pNode->pNext = 0;
00422 
00423   sqlite3_bind_int64(pRtree->pReadNode, 1, iNode);
00424   rc = sqlite3_step(pRtree->pReadNode);
00425   if( rc==SQLITE_ROW ){
00426     const u8 *zBlob = sqlite3_column_blob(pRtree->pReadNode, 0);
00427     memcpy(pNode->zData, zBlob, pRtree->iNodeSize);
00428     nodeReference(pParent);
00429   }else{
00430     sqlite3_free(pNode);
00431     pNode = 0;
00432   }
00433 
00434   *ppNode = pNode;
00435   rc = sqlite3_reset(pRtree->pReadNode);
00436 
00437   if( rc==SQLITE_OK && iNode==1 ){
00438     pRtree->iDepth = readInt16(pNode->zData);
00439   }
00440 
00441   assert( (rc==SQLITE_OK && pNode) || (pNode==0 && rc!=SQLITE_OK) );
00442   nodeHashInsert(pRtree, pNode);
00443 
00444   return rc;
00445 }
00446 
00447 /*
00448 ** Overwrite cell iCell of node pNode with the contents of pCell.
00449 */
00450 static void nodeOverwriteCell(
00451   Rtree *pRtree, 
00452   RtreeNode *pNode,  
00453   RtreeCell *pCell, 
00454   int iCell
00455 ){
00456   int ii;
00457   u8 *p = &pNode->zData[4 + pRtree->nBytesPerCell*iCell];
00458   p += writeInt64(p, pCell->iRowid);
00459   for(ii=0; ii<(pRtree->nDim*2); ii++){
00460     p += writeCoord(p, &pCell->aCoord[ii]);
00461   }
00462   pNode->isDirty = 1;
00463 }
00464 
00465 /*
00466 ** Remove cell the cell with index iCell from node pNode.
00467 */
00468 static void nodeDeleteCell(Rtree *pRtree, RtreeNode *pNode, int iCell){
00469   u8 *pDst = &pNode->zData[4 + pRtree->nBytesPerCell*iCell];
00470   u8 *pSrc = &pDst[pRtree->nBytesPerCell];
00471   int nByte = (NCELL(pNode) - iCell - 1) * pRtree->nBytesPerCell;
00472   memmove(pDst, pSrc, nByte);
00473   writeInt16(&pNode->zData[2], NCELL(pNode)-1);
00474   pNode->isDirty = 1;
00475 }
00476 
00477 /*
00478 ** Insert the contents of cell pCell into node pNode. If the insert
00479 ** is successful, return SQLITE_OK.
00480 **
00481 ** If there is not enough free space in pNode, return SQLITE_FULL.
00482 */
00483 static int
00484 nodeInsertCell(
00485   Rtree *pRtree, 
00486   RtreeNode *pNode, 
00487   RtreeCell *pCell 
00488 ){
00489   int nCell;                    /* Current number of cells in pNode */
00490   int nMaxCell;                 /* Maximum number of cells for pNode */
00491 
00492   nMaxCell = (pRtree->iNodeSize-4)/pRtree->nBytesPerCell;
00493   nCell = NCELL(pNode);
00494 
00495   assert(nCell<=nMaxCell);
00496 
00497   if( nCell<nMaxCell ){
00498     nodeOverwriteCell(pRtree, pNode, pCell, nCell);
00499     writeInt16(&pNode->zData[2], nCell+1);
00500     pNode->isDirty = 1;
00501   }
00502 
00503   return (nCell==nMaxCell);
00504 }
00505 
00506 /*
00507 ** If the node is dirty, write it out to the database.
00508 */
00509 static int
00510 nodeWrite(Rtree *pRtree, RtreeNode *pNode){
00511   int rc = SQLITE_OK;
00512   if( pNode->isDirty ){
00513     sqlite3_stmt *p = pRtree->pWriteNode;
00514     if( pNode->iNode ){
00515       sqlite3_bind_int64(p, 1, pNode->iNode);
00516     }else{
00517       sqlite3_bind_null(p, 1);
00518     }
00519     sqlite3_bind_blob(p, 2, pNode->zData, pRtree->iNodeSize, SQLITE_STATIC);
00520     sqlite3_step(p);
00521     pNode->isDirty = 0;
00522     rc = sqlite3_reset(p);
00523     if( pNode->iNode==0 && rc==SQLITE_OK ){
00524       pNode->iNode = sqlite3_last_insert_rowid(pRtree->db);
00525       nodeHashInsert(pRtree, pNode);
00526     }
00527   }
00528   return rc;
00529 }
00530 
00531 /*
00532 ** Release a reference to a node. If the node is dirty and the reference
00533 ** count drops to zero, the node data is written to the database.
00534 */
00535 static int
00536 nodeRelease(Rtree *pRtree, RtreeNode *pNode){
00537   int rc = SQLITE_OK;
00538   if( pNode ){
00539     assert( pNode->nRef>0 );
00540     pNode->nRef--;
00541     if( pNode->nRef==0 ){
00542       if( pNode->iNode==1 ){
00543         pRtree->iDepth = -1;
00544       }
00545       if( pNode->pParent ){
00546         rc = nodeRelease(pRtree, pNode->pParent);
00547       }
00548       if( rc==SQLITE_OK ){
00549         rc = nodeWrite(pRtree, pNode);
00550       }
00551       nodeHashDelete(pRtree, pNode);
00552       sqlite3_free(pNode);
00553     }
00554   }
00555   return rc;
00556 }
00557 
00558 /*
00559 ** Return the 64-bit integer value associated with cell iCell of
00560 ** node pNode. If pNode is a leaf node, this is a rowid. If it is
00561 ** an internal node, then the 64-bit integer is a child page number.
00562 */
00563 static i64 nodeGetRowid(
00564   Rtree *pRtree, 
00565   RtreeNode *pNode, 
00566   int iCell
00567 ){
00568   assert( iCell<NCELL(pNode) );
00569   return readInt64(&pNode->zData[4 + pRtree->nBytesPerCell*iCell]);
00570 }
00571 
00572 /*
00573 ** Return coordinate iCoord from cell iCell in node pNode.
00574 */
00575 static void nodeGetCoord(
00576   Rtree *pRtree, 
00577   RtreeNode *pNode, 
00578   int iCell,
00579   int iCoord,
00580   RtreeCoord *pCoord           /* Space to write result to */
00581 ){
00582   readCoord(&pNode->zData[12 + pRtree->nBytesPerCell*iCell + 4*iCoord], pCoord);
00583 }
00584 
00585 /*
00586 ** Deserialize cell iCell of node pNode. Populate the structure pointed
00587 ** to by pCell with the results.
00588 */
00589 static void nodeGetCell(
00590   Rtree *pRtree, 
00591   RtreeNode *pNode, 
00592   int iCell,
00593   RtreeCell *pCell
00594 ){
00595   int ii;
00596   pCell->iRowid = nodeGetRowid(pRtree, pNode, iCell);
00597   for(ii=0; ii<pRtree->nDim*2; ii++){
00598     nodeGetCoord(pRtree, pNode, iCell, ii, &pCell->aCoord[ii]);
00599   }
00600 }
00601 
00602 
00603 /* Forward declaration for the function that does the work of
00604 ** the virtual table module xCreate() and xConnect() methods.
00605 */
00606 static int rtreeInit(
00607   sqlite3 *, void *, int, const char *const*, sqlite3_vtab **, char **, int
00608 );
00609 
00610 /* 
00611 ** Rtree virtual table module xCreate method.
00612 */
00613 static int rtreeCreate(
00614   sqlite3 *db,
00615   void *pAux,
00616   int argc, const char *const*argv,
00617   sqlite3_vtab **ppVtab,
00618   char **pzErr
00619 ){
00620   return rtreeInit(db, pAux, argc, argv, ppVtab, pzErr, 1);
00621 }
00622 
00623 /* 
00624 ** Rtree virtual table module xConnect method.
00625 */
00626 static int rtreeConnect(
00627   sqlite3 *db,
00628   void *pAux,
00629   int argc, const char *const*argv,
00630   sqlite3_vtab **ppVtab,
00631   char **pzErr
00632 ){
00633   return rtreeInit(db, pAux, argc, argv, ppVtab, pzErr, 0);
00634 }
00635 
00636 /*
00637 ** Increment the r-tree reference count.
00638 */
00639 static void rtreeReference(Rtree *pRtree){
00640   pRtree->nBusy++;
00641 }
00642 
00643 /*
00644 ** Decrement the r-tree reference count. When the reference count reaches
00645 ** zero the structure is deleted.
00646 */
00647 static void rtreeRelease(Rtree *pRtree){
00648   pRtree->nBusy--;
00649   if( pRtree->nBusy==0 ){
00650     sqlite3_finalize(pRtree->pReadNode);
00651     sqlite3_finalize(pRtree->pWriteNode);
00652     sqlite3_finalize(pRtree->pDeleteNode);
00653     sqlite3_finalize(pRtree->pReadRowid);
00654     sqlite3_finalize(pRtree->pWriteRowid);
00655     sqlite3_finalize(pRtree->pDeleteRowid);
00656     sqlite3_finalize(pRtree->pReadParent);
00657     sqlite3_finalize(pRtree->pWriteParent);
00658     sqlite3_finalize(pRtree->pDeleteParent);
00659     sqlite3_free(pRtree);
00660   }
00661 }
00662 
00663 /* 
00664 ** Rtree virtual table module xDisconnect method.
00665 */
00666 static int rtreeDisconnect(sqlite3_vtab *pVtab){
00667   rtreeRelease((Rtree *)pVtab);
00668   return SQLITE_OK;
00669 }
00670 
00671 /* 
00672 ** Rtree virtual table module xDestroy method.
00673 */
00674 static int rtreeDestroy(sqlite3_vtab *pVtab){
00675   Rtree *pRtree = (Rtree *)pVtab;
00676   int rc;
00677   char *zCreate = sqlite3_mprintf(
00678     "DROP TABLE '%q'.'%q_node';"
00679     "DROP TABLE '%q'.'%q_rowid';"
00680     "DROP TABLE '%q'.'%q_parent';",
00681     pRtree->zDb, pRtree->zName, 
00682     pRtree->zDb, pRtree->zName,
00683     pRtree->zDb, pRtree->zName
00684   );
00685   if( !zCreate ){
00686     rc = SQLITE_NOMEM;
00687   }else{
00688     rc = sqlite3_exec(pRtree->db, zCreate, 0, 0, 0);
00689     sqlite3_free(zCreate);
00690   }
00691   if( rc==SQLITE_OK ){
00692     rtreeRelease(pRtree);
00693   }
00694 
00695   return rc;
00696 }
00697 
00698 /* 
00699 ** Rtree virtual table module xOpen method.
00700 */
00701 static int rtreeOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
00702   int rc = SQLITE_NOMEM;
00703   RtreeCursor *pCsr;
00704 
00705   pCsr = (RtreeCursor *)sqlite3_malloc(sizeof(RtreeCursor));
00706   if( pCsr ){
00707     memset(pCsr, 0, sizeof(RtreeCursor));
00708     pCsr->base.pVtab = pVTab;
00709     rc = SQLITE_OK;
00710   }
00711   *ppCursor = (sqlite3_vtab_cursor *)pCsr;
00712 
00713   return rc;
00714 }
00715 
00716 /* 
00717 ** Rtree virtual table module xClose method.
00718 */
00719 static int rtreeClose(sqlite3_vtab_cursor *cur){
00720   Rtree *pRtree = (Rtree *)(cur->pVtab);
00721   int rc;
00722   RtreeCursor *pCsr = (RtreeCursor *)cur;
00723   sqlite3_free(pCsr->aConstraint);
00724   rc = nodeRelease(pRtree, pCsr->pNode);
00725   sqlite3_free(pCsr);
00726   return rc;
00727 }
00728 
00729 /*
00730 ** Rtree virtual table module xEof method.
00731 **
00732 ** Return non-zero if the cursor does not currently point to a valid 
00733 ** record (i.e if the scan has finished), or zero otherwise.
00734 */
00735 static int rtreeEof(sqlite3_vtab_cursor *cur){
00736   RtreeCursor *pCsr = (RtreeCursor *)cur;
00737   return (pCsr->pNode==0);
00738 }
00739 
00740 /* 
00741 ** Cursor pCursor currently points to a cell in a non-leaf page.
00742 ** Return true if the sub-tree headed by the cell is filtered
00743 ** (excluded) by the constraints in the pCursor->aConstraint[] 
00744 ** array, or false otherwise.
00745 */
00746 static int testRtreeCell(Rtree *pRtree, RtreeCursor *pCursor){
00747   RtreeCell cell;
00748   int ii;
00749   int bRes = 0;
00750 
00751   nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell);
00752   for(ii=0; bRes==0 && ii<pCursor->nConstraint; ii++){
00753     RtreeConstraint *p = &pCursor->aConstraint[ii];
00754     double cell_min = DCOORD(cell.aCoord[(p->iCoord>>1)*2]);
00755     double cell_max = DCOORD(cell.aCoord[(p->iCoord>>1)*2+1]);
00756 
00757     assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE 
00758         || p->op==RTREE_GT || p->op==RTREE_EQ
00759     );
00760 
00761     switch( p->op ){
00762       case RTREE_LE: case RTREE_LT: bRes = p->rValue<cell_min; break;
00763       case RTREE_GE: case RTREE_GT: bRes = p->rValue>cell_max; break;
00764       case RTREE_EQ: 
00765         bRes = (p->rValue>cell_max || p->rValue<cell_min);
00766         break;
00767     }
00768   }
00769 
00770   return bRes;
00771 }
00772 
00773 /* 
00774 ** Return true if the cell that cursor pCursor currently points to
00775 ** would be filtered (excluded) by the constraints in the 
00776 ** pCursor->aConstraint[] array, or false otherwise.
00777 **
00778 ** This function assumes that the cell is part of a leaf node.
00779 */
00780 static int testRtreeEntry(Rtree *pRtree, RtreeCursor *pCursor){
00781   RtreeCell cell;
00782   int ii;
00783 
00784   nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell);
00785   for(ii=0; ii<pCursor->nConstraint; ii++){
00786     RtreeConstraint *p = &pCursor->aConstraint[ii];
00787     double coord = DCOORD(cell.aCoord[p->iCoord]);
00788     int res;
00789     assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE 
00790         || p->op==RTREE_GT || p->op==RTREE_EQ
00791     );
00792     switch( p->op ){
00793       case RTREE_LE: res = (coord<=p->rValue); break;
00794       case RTREE_LT: res = (coord<p->rValue);  break;
00795       case RTREE_GE: res = (coord>=p->rValue); break;
00796       case RTREE_GT: res = (coord>p->rValue);  break;
00797       case RTREE_EQ: res = (coord==p->rValue); break;
00798     }
00799 
00800     if( !res ) return 1;
00801   }
00802 
00803   return 0;
00804 }
00805 
00806 /*
00807 ** Cursor pCursor currently points at a node that heads a sub-tree of
00808 ** height iHeight (if iHeight==0, then the node is a leaf). Descend
00809 ** to point to the left-most cell of the sub-tree that matches the 
00810 ** configured constraints.
00811 */
00812 static int descendToCell(
00813   Rtree *pRtree, 
00814   RtreeCursor *pCursor, 
00815   int iHeight,
00816   int *pEof                 /* OUT: Set to true if cannot descend */
00817 ){
00818   int isEof;
00819   int rc;
00820   int ii;
00821   RtreeNode *pChild;
00822   sqlite3_int64 iRowid;
00823 
00824   RtreeNode *pSavedNode = pCursor->pNode;
00825   int iSavedCell = pCursor->iCell;
00826 
00827   assert( iHeight>=0 );
00828 
00829   if( iHeight==0 ){
00830     isEof = testRtreeEntry(pRtree, pCursor);
00831   }else{
00832     isEof = testRtreeCell(pRtree, pCursor);
00833   }
00834   if( isEof || iHeight==0 ){
00835     *pEof = isEof;
00836     return SQLITE_OK;
00837   }
00838 
00839   iRowid = nodeGetRowid(pRtree, pCursor->pNode, pCursor->iCell);
00840   rc = nodeAcquire(pRtree, iRowid, pCursor->pNode, &pChild);
00841   if( rc!=SQLITE_OK ){
00842     return rc;
00843   }
00844 
00845   nodeRelease(pRtree, pCursor->pNode);
00846   pCursor->pNode = pChild;
00847   isEof = 1;
00848   for(ii=0; isEof && ii<NCELL(pChild); ii++){
00849     pCursor->iCell = ii;
00850     rc = descendToCell(pRtree, pCursor, iHeight-1, &isEof);
00851     if( rc!=SQLITE_OK ){
00852       return rc;
00853     }
00854   }
00855 
00856   if( isEof ){
00857     assert( pCursor->pNode==pChild );
00858     nodeReference(pSavedNode);
00859     nodeRelease(pRtree, pChild);
00860     pCursor->pNode = pSavedNode;
00861     pCursor->iCell = iSavedCell;
00862   }
00863 
00864   *pEof = isEof;
00865   return SQLITE_OK;
00866 }
00867 
00868 /*
00869 ** One of the cells in node pNode is guaranteed to have a 64-bit 
00870 ** integer value equal to iRowid. Return the index of this cell.
00871 */
00872 static int nodeRowidIndex(Rtree *pRtree, RtreeNode *pNode, i64 iRowid){
00873   int ii;
00874   for(ii=0; nodeGetRowid(pRtree, pNode, ii)!=iRowid; ii++){
00875     assert( ii<(NCELL(pNode)-1) );
00876   }
00877   return ii;
00878 }
00879 
00880 /*
00881 ** Return the index of the cell containing a pointer to node pNode
00882 ** in its parent. If pNode is the root node, return -1.
00883 */
00884 static int nodeParentIndex(Rtree *pRtree, RtreeNode *pNode){
00885   RtreeNode *pParent = pNode->pParent;
00886   if( pParent ){
00887     return nodeRowidIndex(pRtree, pParent, pNode->iNode);
00888   }
00889   return -1;
00890 }
00891 
00892 /* 
00893 ** Rtree virtual table module xNext method.
00894 */
00895 static int rtreeNext(sqlite3_vtab_cursor *pVtabCursor){
00896   Rtree *pRtree = (Rtree *)(pVtabCursor->pVtab);
00897   RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor;
00898   int rc = SQLITE_OK;
00899 
00900   if( pCsr->iStrategy==1 ){
00901     /* This "scan" is a direct lookup by rowid. There is no next entry. */
00902     nodeRelease(pRtree, pCsr->pNode);
00903     pCsr->pNode = 0;
00904   }
00905 
00906   else if( pCsr->pNode ){
00907     /* Move to the next entry that matches the configured constraints. */
00908     int iHeight = 0;
00909     while( pCsr->pNode ){
00910       RtreeNode *pNode = pCsr->pNode;
00911       int nCell = NCELL(pNode);
00912       for(pCsr->iCell++; pCsr->iCell<nCell; pCsr->iCell++){
00913         int isEof;
00914         rc = descendToCell(pRtree, pCsr, iHeight, &isEof);
00915         if( rc!=SQLITE_OK || !isEof ){
00916           return rc;
00917         }
00918       }
00919       pCsr->pNode = pNode->pParent;
00920       pCsr->iCell = nodeParentIndex(pRtree, pNode);
00921       nodeReference(pCsr->pNode);
00922       nodeRelease(pRtree, pNode);
00923       iHeight++;
00924     }
00925   }
00926 
00927   return rc;
00928 }
00929 
00930 /* 
00931 ** Rtree virtual table module xRowid method.
00932 */
00933 static int rtreeRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *pRowid){
00934   Rtree *pRtree = (Rtree *)pVtabCursor->pVtab;
00935   RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor;
00936 
00937   assert(pCsr->pNode);
00938   *pRowid = nodeGetRowid(pRtree, pCsr->pNode, pCsr->iCell);
00939 
00940   return SQLITE_OK;
00941 }
00942 
00943 /* 
00944 ** Rtree virtual table module xColumn method.
00945 */
00946 static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
00947   Rtree *pRtree = (Rtree *)cur->pVtab;
00948   RtreeCursor *pCsr = (RtreeCursor *)cur;
00949 
00950   if( i==0 ){
00951     i64 iRowid = nodeGetRowid(pRtree, pCsr->pNode, pCsr->iCell);
00952     sqlite3_result_int64(ctx, iRowid);
00953   }else{
00954     RtreeCoord c;
00955     nodeGetCoord(pRtree, pCsr->pNode, pCsr->iCell, i-1, &c);
00956     if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
00957       sqlite3_result_double(ctx, c.f);
00958     }else{
00959       assert( pRtree->eCoordType==RTREE_COORD_INT32 );
00960       sqlite3_result_int(ctx, c.i);
00961     }
00962   }
00963 
00964   return SQLITE_OK;
00965 }
00966 
00967 /* 
00968 ** Use nodeAcquire() to obtain the leaf node containing the record with 
00969 ** rowid iRowid. If successful, set *ppLeaf to point to the node and
00970 ** return SQLITE_OK. If there is no such record in the table, set
00971 ** *ppLeaf to 0 and return SQLITE_OK. If an error occurs, set *ppLeaf
00972 ** to zero and return an SQLite error code.
00973 */
00974 static int findLeafNode(Rtree *pRtree, i64 iRowid, RtreeNode **ppLeaf){
00975   int rc;
00976   *ppLeaf = 0;
00977   sqlite3_bind_int64(pRtree->pReadRowid, 1, iRowid);
00978   if( sqlite3_step(pRtree->pReadRowid)==SQLITE_ROW ){
00979     i64 iNode = sqlite3_column_int64(pRtree->pReadRowid, 0);
00980     rc = nodeAcquire(pRtree, iNode, 0, ppLeaf);
00981     sqlite3_reset(pRtree->pReadRowid);
00982   }else{
00983     rc = sqlite3_reset(pRtree->pReadRowid);
00984   }
00985   return rc;
00986 }
00987 
00988 
00989 /* 
00990 ** Rtree virtual table module xFilter method.
00991 */
00992 static int rtreeFilter(
00993   sqlite3_vtab_cursor *pVtabCursor, 
00994   int idxNum, const char *idxStr,
00995   int argc, sqlite3_value **argv
00996 ){
00997   Rtree *pRtree = (Rtree *)pVtabCursor->pVtab;
00998   RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor;
00999 
01000   RtreeNode *pRoot = 0;
01001   int ii;
01002   int rc = SQLITE_OK;
01003 
01004   rtreeReference(pRtree);
01005 
01006   sqlite3_free(pCsr->aConstraint);
01007   pCsr->aConstraint = 0;
01008   pCsr->iStrategy = idxNum;
01009 
01010   if( idxNum==1 ){
01011     /* Special case - lookup by rowid. */
01012     RtreeNode *pLeaf;        /* Leaf on which the required cell resides */
01013     i64 iRowid = sqlite3_value_int64(argv[0]);
01014     rc = findLeafNode(pRtree, iRowid, &pLeaf);
01015     pCsr->pNode = pLeaf; 
01016     if( pLeaf && rc==SQLITE_OK ){
01017       pCsr->iCell = nodeRowidIndex(pRtree, pLeaf, iRowid);
01018     }
01019   }else{
01020     /* Normal case - r-tree scan. Set up the RtreeCursor.aConstraint array 
01021     ** with the configured constraints. 
01022     */
01023     if( argc>0 ){
01024       pCsr->aConstraint = sqlite3_malloc(sizeof(RtreeConstraint)*argc);
01025       pCsr->nConstraint = argc;
01026       if( !pCsr->aConstraint ){
01027         rc = SQLITE_NOMEM;
01028       }else{
01029         assert( (idxStr==0 && argc==0) || strlen(idxStr)==argc*2 );
01030         for(ii=0; ii<argc; ii++){
01031           RtreeConstraint *p = &pCsr->aConstraint[ii];
01032           p->op = idxStr[ii*2];
01033           p->iCoord = idxStr[ii*2+1]-'a';
01034           p->rValue = sqlite3_value_double(argv[ii]);
01035         }
01036       }
01037     }
01038   
01039     if( rc==SQLITE_OK ){
01040       pCsr->pNode = 0;
01041       rc = nodeAcquire(pRtree, 1, 0, &pRoot);
01042     }
01043     if( rc==SQLITE_OK ){
01044       int isEof = 1;
01045       int nCell = NCELL(pRoot);
01046       pCsr->pNode = pRoot;
01047       for(pCsr->iCell=0; rc==SQLITE_OK && pCsr->iCell<nCell; pCsr->iCell++){
01048         assert( pCsr->pNode==pRoot );
01049         rc = descendToCell(pRtree, pCsr, pRtree->iDepth, &isEof);
01050         if( !isEof ){
01051           break;
01052         }
01053       }
01054       if( rc==SQLITE_OK && isEof ){
01055         assert( pCsr->pNode==pRoot );
01056         nodeRelease(pRtree, pRoot);
01057         pCsr->pNode = 0;
01058       }
01059       assert( rc!=SQLITE_OK || !pCsr->pNode || pCsr->iCell<NCELL(pCsr->pNode) );
01060     }
01061   }
01062 
01063   rtreeRelease(pRtree);
01064   return rc;
01065 }
01066 
01067 /*
01068 ** Rtree virtual table module xBestIndex method. There are three
01069 ** table scan strategies to choose from (in order from most to 
01070 ** least desirable):
01071 **
01072 **   idxNum     idxStr        Strategy
01073 **   ------------------------------------------------
01074 **     1        Unused        Direct lookup by rowid.
01075 **     2        See below     R-tree query.
01076 **     3        Unused        Full table scan.
01077 **   ------------------------------------------------
01078 **
01079 ** If strategy 1 or 3 is used, then idxStr is not meaningful. If strategy
01080 ** 2 is used, idxStr is formatted to contain 2 bytes for each 
01081 ** constraint used. The first two bytes of idxStr correspond to 
01082 ** the constraint in sqlite3_index_info.aConstraintUsage[] with
01083 ** (argvIndex==1) etc.
01084 **
01085 ** The first of each pair of bytes in idxStr identifies the constraint
01086 ** operator as follows:
01087 **
01088 **   Operator    Byte Value
01089 **   ----------------------
01090 **      =        0x41 ('A')
01091 **     <=        0x42 ('B')
01092 **      <        0x43 ('C')
01093 **     >=        0x44 ('D')
01094 **      >        0x45 ('E')
01095 **   ----------------------
01096 **
01097 ** The second of each pair of bytes identifies the coordinate column
01098 ** to which the constraint applies. The leftmost coordinate column
01099 ** is 'a', the second from the left 'b' etc.
01100 */
01101 static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
01102   int rc = SQLITE_OK;
01103   int ii, cCol;
01104 
01105   int iIdx = 0;
01106   char zIdxStr[RTREE_MAX_DIMENSIONS*8+1];
01107   memset(zIdxStr, 0, sizeof(zIdxStr));
01108 
01109   assert( pIdxInfo->idxStr==0 );
01110   for(ii=0; ii<pIdxInfo->nConstraint; ii++){
01111     struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii];
01112 
01113     if( p->usable && p->iColumn==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){
01114       /* We have an equality constraint on the rowid. Use strategy 1. */
01115       int jj;
01116       for(jj=0; jj<ii; jj++){
01117         pIdxInfo->aConstraintUsage[jj].argvIndex = 0;
01118         pIdxInfo->aConstraintUsage[jj].omit = 0;
01119       }
01120       pIdxInfo->idxNum = 1;
01121       pIdxInfo->aConstraintUsage[ii].argvIndex = 1;
01122       pIdxInfo->aConstraintUsage[jj].omit = 1;
01123 
01124       /* This strategy involves a two rowid lookups on an B-Tree structures
01125       ** and then a linear search of an R-Tree node. This should be 
01126       ** considered almost as quick as a direct rowid lookup (for which 
01127       ** sqlite uses an internal cost of 0.0).
01128       */ 
01129       pIdxInfo->estimatedCost = 10.0;
01130       return SQLITE_OK;
01131     }
01132 
01133     if( p->usable && p->iColumn>0 ){
01134       u8 op = 0;
01135       switch( p->op ){
01136         case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; break;
01137         case SQLITE_INDEX_CONSTRAINT_GT: op = RTREE_GT; break;
01138         case SQLITE_INDEX_CONSTRAINT_LE: op = RTREE_LE; break;
01139         case SQLITE_INDEX_CONSTRAINT_LT: op = RTREE_LT; break;
01140         case SQLITE_INDEX_CONSTRAINT_GE: op = RTREE_GE; break;
01141       }
01142       if( op ){
01143         /* Make sure this particular constraint has not been used before.
01144         ** If it has been used before, ignore it.
01145         **
01146         ** A <= or < can be used if there is a prior >= or >.
01147         ** A >= or > can be used if there is a prior < or <=.
01148         ** A <= or < is disqualified if there is a prior <=, <, or ==.
01149         ** A >= or > is disqualified if there is a prior >=, >, or ==.
01150         ** A == is disqualifed if there is any prior constraint.
01151         */
01152         int j, opmsk;
01153         static const unsigned char compatible[] = { 0, 0, 1, 1, 2, 2 };
01154         assert( compatible[RTREE_EQ & 7]==0 );
01155         assert( compatible[RTREE_LT & 7]==1 );
01156         assert( compatible[RTREE_LE & 7]==1 );
01157         assert( compatible[RTREE_GT & 7]==2 );
01158         assert( compatible[RTREE_GE & 7]==2 );
01159         cCol = p->iColumn - 1 + 'a';
01160         opmsk = compatible[op & 7];
01161         for(j=0; j<iIdx; j+=2){
01162           if( zIdxStr[j+1]==cCol && (compatible[zIdxStr[j] & 7] & opmsk)!=0 ){
01163             op = 0;
01164             break;
01165           }
01166         }
01167       }
01168       if( op ){
01169         assert( iIdx<sizeof(zIdxStr)-1 );
01170         zIdxStr[iIdx++] = op;
01171         zIdxStr[iIdx++] = cCol;
01172         pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2);
01173         pIdxInfo->aConstraintUsage[ii].omit = 1;
01174       }
01175     }
01176   }
01177 
01178   pIdxInfo->idxNum = 2;
01179   pIdxInfo->needToFreeIdxStr = 1;
01180   if( iIdx>0 && 0==(pIdxInfo->idxStr = sqlite3_mprintf("%s", zIdxStr)) ){
01181     return SQLITE_NOMEM;
01182   }
01183   assert( iIdx>=0 );
01184   pIdxInfo->estimatedCost = (2000000.0 / (double)(iIdx + 1));
01185   return rc;
01186 }
01187 
01188 /*
01189 ** Return the N-dimensional volumn of the cell stored in *p.
01190 */
01191 static float cellArea(Rtree *pRtree, RtreeCell *p){
01192   float area = 1.0;
01193   int ii;
01194   for(ii=0; ii<(pRtree->nDim*2); ii+=2){
01195     area = area * (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii]));
01196   }
01197   return area;
01198 }
01199 
01200 /*
01201 ** Return the margin length of cell p. The margin length is the sum
01202 ** of the objects size in each dimension.
01203 */
01204 static float cellMargin(Rtree *pRtree, RtreeCell *p){
01205   float margin = 0.0;
01206   int ii;
01207   for(ii=0; ii<(pRtree->nDim*2); ii+=2){
01208     margin += (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii]));
01209   }
01210   return margin;
01211 }
01212 
01213 /*
01214 ** Store the union of cells p1 and p2 in p1.
01215 */
01216 static void cellUnion(Rtree *pRtree, RtreeCell *p1, RtreeCell *p2){
01217   int ii;
01218   if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
01219     for(ii=0; ii<(pRtree->nDim*2); ii+=2){
01220       p1->aCoord[ii].f = MIN(p1->aCoord[ii].f, p2->aCoord[ii].f);
01221       p1->aCoord[ii+1].f = MAX(p1->aCoord[ii+1].f, p2->aCoord[ii+1].f);
01222     }
01223   }else{
01224     for(ii=0; ii<(pRtree->nDim*2); ii+=2){
01225       p1->aCoord[ii].i = MIN(p1->aCoord[ii].i, p2->aCoord[ii].i);
01226       p1->aCoord[ii+1].i = MAX(p1->aCoord[ii+1].i, p2->aCoord[ii+1].i);
01227     }
01228   }
01229 }
01230 
01231 /*
01232 ** Return true if the area covered by p2 is a subset of the area covered
01233 ** by p1. False otherwise.
01234 */
01235 static int cellContains(Rtree *pRtree, RtreeCell *p1, RtreeCell *p2){
01236   int ii;
01237   int isInt = (pRtree->eCoordType==RTREE_COORD_INT32);
01238   for(ii=0; ii<(pRtree->nDim*2); ii+=2){
01239     RtreeCoord *a1 = &p1->aCoord[ii];
01240     RtreeCoord *a2 = &p2->aCoord[ii];
01241     if( (!isInt && (a2[0].f<a1[0].f || a2[1].f>a1[1].f)) 
01242      || ( isInt && (a2[0].i<a1[0].i || a2[1].i>a1[1].i)) 
01243     ){
01244       return 0;
01245     }
01246   }
01247   return 1;
01248 }
01249 
01250 /*
01251 ** Return the amount cell p would grow by if it were unioned with pCell.
01252 */
01253 static float cellGrowth(Rtree *pRtree, RtreeCell *p, RtreeCell *pCell){
01254   float area;
01255   RtreeCell cell;
01256   memcpy(&cell, p, sizeof(RtreeCell));
01257   area = cellArea(pRtree, &cell);
01258   cellUnion(pRtree, &cell, pCell);
01259   return (cellArea(pRtree, &cell)-area);
01260 }
01261 
01262 #if VARIANT_RSTARTREE_CHOOSESUBTREE || VARIANT_RSTARTREE_SPLIT
01263 static float cellOverlap(
01264   Rtree *pRtree, 
01265   RtreeCell *p, 
01266   RtreeCell *aCell, 
01267   int nCell, 
01268   int iExclude
01269 ){
01270   int ii;
01271   float overlap = 0.0;
01272   for(ii=0; ii<nCell; ii++){
01273     if( ii!=iExclude ){
01274       int jj;
01275       float o = 1.0;
01276       for(jj=0; jj<(pRtree->nDim*2); jj+=2){
01277         double x1;
01278         double x2;
01279 
01280         x1 = MAX(DCOORD(p->aCoord[jj]), DCOORD(aCell[ii].aCoord[jj]));
01281         x2 = MIN(DCOORD(p->aCoord[jj+1]), DCOORD(aCell[ii].aCoord[jj+1]));
01282 
01283         if( x2<x1 ){
01284           o = 0.0;
01285           break;
01286         }else{
01287           o = o * (x2-x1);
01288         }
01289       }
01290       overlap += o;
01291     }
01292   }
01293   return overlap;
01294 }
01295 #endif
01296 
01297 #if VARIANT_RSTARTREE_CHOOSESUBTREE
01298 static float cellOverlapEnlargement(
01299   Rtree *pRtree, 
01300   RtreeCell *p, 
01301   RtreeCell *pInsert, 
01302   RtreeCell *aCell, 
01303   int nCell, 
01304   int iExclude
01305 ){
01306   float before;
01307   float after;
01308   before = cellOverlap(pRtree, p, aCell, nCell, iExclude);
01309   cellUnion(pRtree, p, pInsert);
01310   after = cellOverlap(pRtree, p, aCell, nCell, iExclude);
01311   return after-before;
01312 }
01313 #endif
01314 
01315 
01316 /*
01317 ** This function implements the ChooseLeaf algorithm from Gutman[84].
01318 ** ChooseSubTree in r*tree terminology.
01319 */
01320 static int ChooseLeaf(
01321   Rtree *pRtree,               /* Rtree table */
01322   RtreeCell *pCell,            /* Cell to insert into rtree */
01323   int iHeight,                 /* Height of sub-tree rooted at pCell */
01324   RtreeNode **ppLeaf           /* OUT: Selected leaf page */
01325 ){
01326   int rc;
01327   int ii;
01328   RtreeNode *pNode;
01329   rc = nodeAcquire(pRtree, 1, 0, &pNode);
01330 
01331   for(ii=0; rc==SQLITE_OK && ii<(pRtree->iDepth-iHeight); ii++){
01332     int iCell;
01333     sqlite3_int64 iBest;
01334 
01335     float fMinGrowth;
01336     float fMinArea;
01337     float fMinOverlap;
01338 
01339     int nCell = NCELL(pNode);
01340     RtreeCell cell;
01341     RtreeNode *pChild;
01342 
01343     RtreeCell *aCell = 0;
01344 
01345 #if VARIANT_RSTARTREE_CHOOSESUBTREE
01346     if( ii==(pRtree->iDepth-1) ){
01347       int jj;
01348       aCell = sqlite3_malloc(sizeof(RtreeCell)*nCell);
01349       if( !aCell ){
01350         rc = SQLITE_NOMEM;
01351         nodeRelease(pRtree, pNode);
01352         pNode = 0;
01353         continue;
01354       }
01355       for(jj=0; jj<nCell; jj++){
01356         nodeGetCell(pRtree, pNode, jj, &aCell[jj]);
01357       }
01358     }
01359 #endif
01360 
01361     /* Select the child node which will be enlarged the least if pCell
01362     ** is inserted into it. Resolve ties by choosing the entry with
01363     ** the smallest area.
01364     */
01365     for(iCell=0; iCell<nCell; iCell++){
01366       float growth;
01367       float area;
01368       float overlap = 0.0;
01369       nodeGetCell(pRtree, pNode, iCell, &cell);
01370       growth = cellGrowth(pRtree, &cell, pCell);
01371       area = cellArea(pRtree, &cell);
01372 #if VARIANT_RSTARTREE_CHOOSESUBTREE
01373       if( ii==(pRtree->iDepth-1) ){
01374         overlap = cellOverlapEnlargement(pRtree,&cell,pCell,aCell,nCell,iCell);
01375       }
01376 #endif
01377       if( (iCell==0) 
01378        || (overlap<fMinOverlap) 
01379        || (overlap==fMinOverlap && growth<fMinGrowth)
01380        || (overlap==fMinOverlap && growth==fMinGrowth && area<fMinArea)
01381       ){
01382         fMinOverlap = overlap;
01383         fMinGrowth = growth;
01384         fMinArea = area;
01385         iBest = cell.iRowid;
01386       }
01387     }
01388 
01389     sqlite3_free(aCell);
01390     rc = nodeAcquire(pRtree, iBest, pNode, &pChild);
01391     nodeRelease(pRtree, pNode);
01392     pNode = pChild;
01393   }
01394 
01395   *ppLeaf = pNode;
01396   return rc;
01397 }
01398 
01399 /*
01400 ** A cell with the same content as pCell has just been inserted into
01401 ** the node pNode. This function updates the bounding box cells in
01402 ** all ancestor elements.
01403 */
01404 static void AdjustTree(
01405   Rtree *pRtree,                    /* Rtree table */
01406   RtreeNode *pNode,                 /* Adjust ancestry of this node. */
01407   RtreeCell *pCell                  /* This cell was just inserted */
01408 ){
01409   RtreeNode *p = pNode;
01410   while( p->pParent ){
01411     RtreeCell cell;
01412     RtreeNode *pParent = p->pParent;
01413     int iCell = nodeParentIndex(pRtree, p);
01414 
01415     nodeGetCell(pRtree, pParent, iCell, &cell);
01416     if( !cellContains(pRtree, &cell, pCell) ){
01417       cellUnion(pRtree, &cell, pCell);
01418       nodeOverwriteCell(pRtree, pParent, &cell, iCell);
01419     }
01420  
01421     p = pParent;
01422   }
01423 }
01424 
01425 /*
01426 ** Write mapping (iRowid->iNode) to the <rtree>_rowid table.
01427 */
01428 static int rowidWrite(Rtree *pRtree, sqlite3_int64 iRowid, sqlite3_int64 iNode){
01429   sqlite3_bind_int64(pRtree->pWriteRowid, 1, iRowid);
01430   sqlite3_bind_int64(pRtree->pWriteRowid, 2, iNode);
01431   sqlite3_step(pRtree->pWriteRowid);
01432   return sqlite3_reset(pRtree->pWriteRowid);
01433 }
01434 
01435 /*
01436 ** Write mapping (iNode->iPar) to the <rtree>_parent table.
01437 */
01438 static int parentWrite(Rtree *pRtree, sqlite3_int64 iNode, sqlite3_int64 iPar){
01439   sqlite3_bind_int64(pRtree->pWriteParent, 1, iNode);
01440   sqlite3_bind_int64(pRtree->pWriteParent, 2, iPar);
01441   sqlite3_step(pRtree->pWriteParent);
01442   return sqlite3_reset(pRtree->pWriteParent);
01443 }
01444 
01445 static int rtreeInsertCell(Rtree *, RtreeNode *, RtreeCell *, int);
01446 
01447 #if VARIANT_GUTTMAN_LINEAR_SPLIT
01448 /*
01449 ** Implementation of the linear variant of the PickNext() function from
01450 ** Guttman[84].
01451 */
01452 static RtreeCell *LinearPickNext(
01453   Rtree *pRtree,
01454   RtreeCell *aCell, 
01455   int nCell, 
01456   RtreeCell *pLeftBox, 
01457   RtreeCell *pRightBox,
01458   int *aiUsed
01459 ){
01460   int ii;
01461   for(ii=0; aiUsed[ii]; ii++);
01462   aiUsed[ii] = 1;
01463   return &aCell[ii];
01464 }
01465 
01466 /*
01467 ** Implementation of the linear variant of the PickSeeds() function from
01468 ** Guttman[84].
01469 */
01470 static void LinearPickSeeds(
01471   Rtree *pRtree,
01472   RtreeCell *aCell, 
01473   int nCell, 
01474   int *piLeftSeed, 
01475   int *piRightSeed
01476 ){
01477   int i;
01478   int iLeftSeed = 0;
01479   int iRightSeed = 1;
01480   float maxNormalInnerWidth = 0.0;
01481 
01482   /* Pick two "seed" cells from the array of cells. The algorithm used
01483   ** here is the LinearPickSeeds algorithm from Gutman[1984]. The 
01484   ** indices of the two seed cells in the array are stored in local
01485   ** variables iLeftSeek and iRightSeed.
01486   */
01487   for(i=0; i<pRtree->nDim; i++){
01488     float x1 = aCell[0].aCoord[i*2];
01489     float x2 = aCell[0].aCoord[i*2+1];
01490     float x3 = x1;
01491     float x4 = x2;
01492     int jj;
01493 
01494     int iCellLeft = 0;
01495     int iCellRight = 0;
01496 
01497     for(jj=1; jj<nCell; jj++){
01498       float left = aCell[jj].aCoord[i*2];
01499       float right = aCell[jj].aCoord[i*2+1];
01500 
01501       if( left<x1 ) x1 = left;
01502       if( right>x4 ) x4 = right;
01503       if( left>x3 ){
01504         x3 = left;
01505         iCellRight = jj;
01506       }
01507       if( right<x2 ){
01508         x2 = right;
01509         iCellLeft = jj;
01510       }
01511     }
01512 
01513     if( x4!=x1 ){
01514       float normalwidth = (x3 - x2) / (x4 - x1);
01515       if( normalwidth>maxNormalInnerWidth ){
01516         iLeftSeed = iCellLeft;
01517         iRightSeed = iCellRight;
01518       }
01519     }
01520   }
01521 
01522   *piLeftSeed = iLeftSeed;
01523   *piRightSeed = iRightSeed;
01524 }
01525 #endif /* VARIANT_GUTTMAN_LINEAR_SPLIT */
01526 
01527 #if VARIANT_GUTTMAN_QUADRATIC_SPLIT
01528 /*
01529 ** Implementation of the quadratic variant of the PickNext() function from
01530 ** Guttman[84].
01531 */
01532 static RtreeCell *QuadraticPickNext(
01533   Rtree *pRtree,
01534   RtreeCell *aCell, 
01535   int nCell, 
01536   RtreeCell *pLeftBox, 
01537   RtreeCell *pRightBox,
01538   int *aiUsed
01539 ){
01540   #define FABS(a) ((a)<0.0?-1.0*(a):(a))
01541 
01542   int iSelect = -1;
01543   float fDiff;
01544   int ii;
01545   for(ii=0; ii<nCell; ii++){
01546     if( aiUsed[ii]==0 ){
01547       float left = cellGrowth(pRtree, pLeftBox, &aCell[ii]);
01548       float right = cellGrowth(pRtree, pLeftBox, &aCell[ii]);
01549       float diff = FABS(right-left);
01550       if( iSelect<0 || diff>fDiff ){
01551         fDiff = diff;
01552         iSelect = ii;
01553       }
01554     }
01555   }
01556   aiUsed[iSelect] = 1;
01557   return &aCell[iSelect];
01558 }
01559 
01560 /*
01561 ** Implementation of the quadratic variant of the PickSeeds() function from
01562 ** Guttman[84].
01563 */
01564 static void QuadraticPickSeeds(
01565   Rtree *pRtree,
01566   RtreeCell *aCell, 
01567   int nCell, 
01568   int *piLeftSeed, 
01569   int *piRightSeed
01570 ){
01571   int ii;
01572   int jj;
01573 
01574   int iLeftSeed = 0;
01575   int iRightSeed = 1;
01576   float fWaste = 0.0;
01577 
01578   for(ii=0; ii<nCell; ii++){
01579     for(jj=ii+1; jj<nCell; jj++){
01580       float right = cellArea(pRtree, &aCell[jj]);
01581       float growth = cellGrowth(pRtree, &aCell[ii], &aCell[jj]);
01582       float waste = growth - right;
01583 
01584       if( waste>fWaste ){
01585         iLeftSeed = ii;
01586         iRightSeed = jj;
01587         fWaste = waste;
01588       }
01589     }
01590   }
01591 
01592   *piLeftSeed = iLeftSeed;
01593   *piRightSeed = iRightSeed;
01594 }
01595 #endif /* VARIANT_GUTTMAN_QUADRATIC_SPLIT */
01596 
01597 /*
01598 ** Arguments aIdx, aDistance and aSpare all point to arrays of size
01599 ** nIdx. The aIdx array contains the set of integers from 0 to 
01600 ** (nIdx-1) in no particular order. This function sorts the values
01601 ** in aIdx according to the indexed values in aDistance. For
01602 ** example, assuming the inputs:
01603 **
01604 **   aIdx      = { 0,   1,   2,   3 }
01605 **   aDistance = { 5.0, 2.0, 7.0, 6.0 }
01606 **
01607 ** this function sets the aIdx array to contain:
01608 **
01609 **   aIdx      = { 0,   1,   2,   3 }
01610 **
01611 ** The aSpare array is used as temporary working space by the
01612 ** sorting algorithm.
01613 */
01614 static void SortByDistance(
01615   int *aIdx, 
01616   int nIdx, 
01617   float *aDistance, 
01618   int *aSpare
01619 ){
01620   if( nIdx>1 ){
01621     int iLeft = 0;
01622     int iRight = 0;
01623 
01624     int nLeft = nIdx/2;
01625     int nRight = nIdx-nLeft;
01626     int *aLeft = aIdx;
01627     int *aRight = &aIdx[nLeft];
01628 
01629     SortByDistance(aLeft, nLeft, aDistance, aSpare);
01630     SortByDistance(aRight, nRight, aDistance, aSpare);
01631 
01632     memcpy(aSpare, aLeft, sizeof(int)*nLeft);
01633     aLeft = aSpare;
01634 
01635     while( iLeft<nLeft || iRight<nRight ){
01636       if( iLeft==nLeft ){
01637         aIdx[iLeft+iRight] = aRight[iRight];
01638         iRight++;
01639       }else if( iRight==nRight ){
01640         aIdx[iLeft+iRight] = aLeft[iLeft];
01641         iLeft++;
01642       }else{
01643         float fLeft = aDistance[aLeft[iLeft]];
01644         float fRight = aDistance[aRight[iRight]];
01645         if( fLeft<fRight ){
01646           aIdx[iLeft+iRight] = aLeft[iLeft];
01647           iLeft++;
01648         }else{
01649           aIdx[iLeft+iRight] = aRight[iRight];
01650           iRight++;
01651         }
01652       }
01653     }
01654 
01655 #if 0
01656     /* Check that the sort worked */
01657     {
01658       int jj;
01659       for(jj=1; jj<nIdx; jj++){
01660         float left = aDistance[aIdx[jj-1]];
01661         float right = aDistance[aIdx[jj]];
01662         assert( left<=right );
01663       }
01664     }
01665 #endif
01666   }
01667 }
01668 
01669 /*
01670 ** Arguments aIdx, aCell and aSpare all point to arrays of size
01671 ** nIdx. The aIdx array contains the set of integers from 0 to 
01672 ** (nIdx-1) in no particular order. This function sorts the values
01673 ** in aIdx according to dimension iDim of the cells in aCell. The
01674 ** minimum value of dimension iDim is considered first, the
01675 ** maximum used to break ties.
01676 **
01677 ** The aSpare array is used as temporary working space by the
01678 ** sorting algorithm.
01679 */
01680 static void SortByDimension(
01681   Rtree *pRtree,
01682   int *aIdx, 
01683   int nIdx, 
01684   int iDim, 
01685   RtreeCell *aCell, 
01686   int *aSpare
01687 ){
01688   if( nIdx>1 ){
01689 
01690     int iLeft = 0;
01691     int iRight = 0;
01692 
01693     int nLeft = nIdx/2;
01694     int nRight = nIdx-nLeft;
01695     int *aLeft = aIdx;
01696     int *aRight = &aIdx[nLeft];
01697 
01698     SortByDimension(pRtree, aLeft, nLeft, iDim, aCell, aSpare);
01699     SortByDimension(pRtree, aRight, nRight, iDim, aCell, aSpare);
01700 
01701     memcpy(aSpare, aLeft, sizeof(int)*nLeft);
01702     aLeft = aSpare;
01703     while( iLeft<nLeft || iRight<nRight ){
01704       double xleft1 = DCOORD(aCell[aLeft[iLeft]].aCoord[iDim*2]);
01705       double xleft2 = DCOORD(aCell[aLeft[iLeft]].aCoord[iDim*2+1]);
01706       double xright1 = DCOORD(aCell[aRight[iRight]].aCoord[iDim*2]);
01707       double xright2 = DCOORD(aCell[aRight[iRight]].aCoord[iDim*2+1]);
01708       if( (iLeft!=nLeft) && ((iRight==nRight)
01709        || (xleft1<xright1)
01710        || (xleft1==xright1 && xleft2<xright2)
01711       )){
01712         aIdx[iLeft+iRight] = aLeft[iLeft];
01713         iLeft++;
01714       }else{
01715         aIdx[iLeft+iRight] = aRight[iRight];
01716         iRight++;
01717       }
01718     }
01719 
01720 #if 0
01721     /* Check that the sort worked */
01722     {
01723       int jj;
01724       for(jj=1; jj<nIdx; jj++){
01725         float xleft1 = aCell[aIdx[jj-1]].aCoord[iDim*2];
01726         float xleft2 = aCell[aIdx[jj-1]].aCoord[iDim*2+1];
01727         float xright1 = aCell[aIdx[jj]].aCoord[iDim*2];
01728         float xright2 = aCell[aIdx[jj]].aCoord[iDim*2+1];
01729         assert( xleft1<=xright1 && (xleft1<xright1 || xleft2<=xright2) );
01730       }
01731     }
01732 #endif
01733   }
01734 }
01735 
01736 #if VARIANT_RSTARTREE_SPLIT
01737 /*
01738 ** Implementation of the R*-tree variant of SplitNode from Beckman[1990].
01739 */
01740 static int splitNodeStartree(
01741   Rtree *pRtree,
01742   RtreeCell *aCell,
01743   int nCell,
01744   RtreeNode *pLeft,
01745   RtreeNode *pRight,
01746   RtreeCell *pBboxLeft,
01747   RtreeCell *pBboxRight
01748 ){
01749   int **aaSorted;
01750   int *aSpare;
01751   int ii;
01752 
01753   int iBestDim;
01754   int iBestSplit;
01755   float fBestMargin;
01756 
01757   int nByte = (pRtree->nDim+1)*(sizeof(int*)+nCell*sizeof(int));
01758 
01759   aaSorted = (int **)sqlite3_malloc(nByte);
01760   if( !aaSorted ){
01761     return SQLITE_NOMEM;
01762   }
01763 
01764   aSpare = &((int *)&aaSorted[pRtree->nDim])[pRtree->nDim*nCell];
01765   memset(aaSorted, 0, nByte);
01766   for(ii=0; ii<pRtree->nDim; ii++){
01767     int jj;
01768     aaSorted[ii] = &((int *)&aaSorted[pRtree->nDim])[ii*nCell];
01769     for(jj=0; jj<nCell; jj++){
01770       aaSorted[ii][jj] = jj;
01771     }
01772     SortByDimension(pRtree, aaSorted[ii], nCell, ii, aCell, aSpare);
01773   }
01774 
01775   for(ii=0; ii<pRtree->nDim; ii++){
01776     float margin = 0.0;
01777     float fBestOverlap;
01778     float fBestArea;
01779     int iBestLeft;
01780     int nLeft;
01781 
01782     for(
01783       nLeft=RTREE_MINCELLS(pRtree); 
01784       nLeft<=(nCell-RTREE_MINCELLS(pRtree)); 
01785       nLeft++
01786     ){
01787       RtreeCell left;
01788       RtreeCell right;
01789       int kk;
01790       float overlap;
01791       float area;
01792 
01793       memcpy(&left, &aCell[aaSorted[ii][0]], sizeof(RtreeCell));
01794       memcpy(&right, &aCell[aaSorted[ii][nCell-1]], sizeof(RtreeCell));
01795       for(kk=1; kk<(nCell-1); kk++){
01796         if( kk<nLeft ){
01797           cellUnion(pRtree, &left, &aCell[aaSorted[ii][kk]]);
01798         }else{
01799           cellUnion(pRtree, &right, &aCell[aaSorted[ii][kk]]);
01800         }
01801       }
01802       margin += cellMargin(pRtree, &left);
01803       margin += cellMargin(pRtree, &right);
01804       overlap = cellOverlap(pRtree, &left, &right, 1, -1);
01805       area = cellArea(pRtree, &left) + cellArea(pRtree, &right);
01806       if( (nLeft==RTREE_MINCELLS(pRtree))
01807        || (overlap<fBestOverlap)
01808        || (overlap==fBestOverlap && area<fBestArea)
01809       ){
01810         iBestLeft = nLeft;
01811         fBestOverlap = overlap;
01812         fBestArea = area;
01813       }
01814     }
01815 
01816     if( ii==0 || margin<fBestMargin ){
01817       iBestDim = ii;
01818       fBestMargin = margin;
01819       iBestSplit = iBestLeft;
01820     }
01821   }
01822 
01823   memcpy(pBboxLeft, &aCell[aaSorted[iBestDim][0]], sizeof(RtreeCell));
01824   memcpy(pBboxRight, &aCell[aaSorted[iBestDim][iBestSplit]], sizeof(RtreeCell));
01825   for(ii=0; ii<nCell; ii++){
01826     RtreeNode *pTarget = (ii<iBestSplit)?pLeft:pRight;
01827     RtreeCell *pBbox = (ii<iBestSplit)?pBboxLeft:pBboxRight;
01828     RtreeCell *pCell = &aCell[aaSorted[iBestDim][ii]];
01829     nodeInsertCell(pRtree, pTarget, pCell);
01830     cellUnion(pRtree, pBbox, pCell);
01831   }
01832 
01833   sqlite3_free(aaSorted);
01834   return SQLITE_OK;
01835 }
01836 #endif
01837 
01838 #if VARIANT_GUTTMAN_SPLIT
01839 /*
01840 ** Implementation of the regular R-tree SplitNode from Guttman[1984].
01841 */
01842 static int splitNodeGuttman(
01843   Rtree *pRtree,
01844   RtreeCell *aCell,
01845   int nCell,
01846   RtreeNode *pLeft,
01847   RtreeNode *pRight,
01848   RtreeCell *pBboxLeft,
01849   RtreeCell *pBboxRight
01850 ){
01851   int iLeftSeed = 0;
01852   int iRightSeed = 1;
01853   int *aiUsed;
01854   int i;
01855 
01856   aiUsed = sqlite3_malloc(sizeof(int)*nCell);
01857   memset(aiUsed, 0, sizeof(int)*nCell);
01858 
01859   PickSeeds(pRtree, aCell, nCell, &iLeftSeed, &iRightSeed);
01860 
01861   memcpy(pBboxLeft, &aCell[iLeftSeed], sizeof(RtreeCell));
01862   memcpy(pBboxRight, &aCell[iRightSeed], sizeof(RtreeCell));
01863   nodeInsertCell(pRtree, pLeft, &aCell[iLeftSeed]);
01864   nodeInsertCell(pRtree, pRight, &aCell[iRightSeed]);
01865   aiUsed[iLeftSeed] = 1;
01866   aiUsed[iRightSeed] = 1;
01867 
01868   for(i=nCell-2; i>0; i--){
01869     RtreeCell *pNext;
01870     pNext = PickNext(pRtree, aCell, nCell, pBboxLeft, pBboxRight, aiUsed);
01871     float diff =  
01872       cellGrowth(pRtree, pBboxLeft, pNext) - 
01873       cellGrowth(pRtree, pBboxRight, pNext)
01874     ;
01875     if( (RTREE_MINCELLS(pRtree)-NCELL(pRight)==i)
01876      || (diff>0.0 && (RTREE_MINCELLS(pRtree)-NCELL(pLeft)!=i))
01877     ){
01878       nodeInsertCell(pRtree, pRight, pNext);
01879       cellUnion(pRtree, pBboxRight, pNext);
01880     }else{
01881       nodeInsertCell(pRtree, pLeft, pNext);
01882       cellUnion(pRtree, pBboxLeft, pNext);
01883     }
01884   }
01885 
01886   sqlite3_free(aiUsed);
01887   return SQLITE_OK;
01888 }
01889 #endif
01890 
01891 static int updateMapping(
01892   Rtree *pRtree, 
01893   i64 iRowid, 
01894   RtreeNode *pNode, 
01895   int iHeight
01896 ){
01897   int (*xSetMapping)(Rtree *, sqlite3_int64, sqlite3_int64);
01898   xSetMapping = ((iHeight==0)?rowidWrite:parentWrite);
01899   if( iHeight>0 ){
01900     RtreeNode *pChild = nodeHashLookup(pRtree, iRowid);
01901     if( pChild ){
01902       nodeRelease(pRtree, pChild->pParent);
01903       nodeReference(pNode);
01904       pChild->pParent = pNode;
01905     }
01906   }
01907   return xSetMapping(pRtree, iRowid, pNode->iNode);
01908 }
01909 
01910 static int SplitNode(
01911   Rtree *pRtree,
01912   RtreeNode *pNode,
01913   RtreeCell *pCell,
01914   int iHeight
01915 ){
01916   int i;
01917   int newCellIsRight = 0;
01918 
01919   int rc = SQLITE_OK;
01920   int nCell = NCELL(pNode);
01921   RtreeCell *aCell;
01922   int *aiUsed;
01923 
01924   RtreeNode *pLeft = 0;
01925   RtreeNode *pRight = 0;
01926 
01927   RtreeCell leftbbox;
01928   RtreeCell rightbbox;
01929 
01930   /* Allocate an array and populate it with a copy of pCell and 
01931   ** all cells from node pLeft. Then zero the original node.
01932   */
01933   aCell = sqlite3_malloc((sizeof(RtreeCell)+sizeof(int))*(nCell+1));
01934   if( !aCell ){
01935     rc = SQLITE_NOMEM;
01936     goto splitnode_out;
01937   }
01938   aiUsed = (int *)&aCell[nCell+1];
01939   memset(aiUsed, 0, sizeof(int)*(nCell+1));
01940   for(i=0; i<nCell; i++){
01941     nodeGetCell(pRtree, pNode, i, &aCell[i]);
01942   }
01943   nodeZero(pRtree, pNode);
01944   memcpy(&aCell[nCell], pCell, sizeof(RtreeCell));
01945   nCell++;
01946 
01947   if( pNode->iNode==1 ){
01948     pRight = nodeNew(pRtree, pNode, 1);
01949     pLeft = nodeNew(pRtree, pNode, 1);
01950     pRtree->iDepth++;
01951     pNode->isDirty = 1;
01952     writeInt16(pNode->zData, pRtree->iDepth);
01953   }else{
01954     pLeft = pNode;
01955     pRight = nodeNew(pRtree, pLeft->pParent, 1);
01956     nodeReference(pLeft);
01957   }
01958 
01959   if( !pLeft || !pRight ){
01960     rc = SQLITE_NOMEM;
01961     goto splitnode_out;
01962   }
01963 
01964   memset(pLeft->zData, 0, pRtree->iNodeSize);
01965   memset(pRight->zData, 0, pRtree->iNodeSize);
01966 
01967   rc = AssignCells(pRtree, aCell, nCell, pLeft, pRight, &leftbbox, &rightbbox);
01968   if( rc!=SQLITE_OK ){
01969     goto splitnode_out;
01970   }
01971 
01972   /* Ensure both child nodes have node numbers assigned to them. */
01973   if( (0==pRight->iNode && SQLITE_OK!=(rc = nodeWrite(pRtree, pRight)))
01974    || (0==pLeft->iNode && SQLITE_OK!=(rc = nodeWrite(pRtree, pLeft)))
01975   ){
01976     goto splitnode_out;
01977   }
01978 
01979   rightbbox.iRowid = pRight->iNode;
01980   leftbbox.iRowid = pLeft->iNode;
01981 
01982   if( pNode->iNode==1 ){
01983     rc = rtreeInsertCell(pRtree, pLeft->pParent, &leftbbox, iHeight+1);
01984     if( rc!=SQLITE_OK ){
01985       goto splitnode_out;
01986     }
01987   }else{
01988     RtreeNode *pParent = pLeft->pParent;
01989     int iCell = nodeParentIndex(pRtree, pLeft);
01990     nodeOverwriteCell(pRtree, pParent, &leftbbox, iCell);
01991     AdjustTree(pRtree, pParent, &leftbbox);
01992   }
01993   if( (rc = rtreeInsertCell(pRtree, pRight->pParent, &rightbbox, iHeight+1)) ){
01994     goto splitnode_out;
01995   }
01996 
01997   for(i=0; i<NCELL(pRight); i++){
01998     i64 iRowid = nodeGetRowid(pRtree, pRight, i);
01999     rc = updateMapping(pRtree, iRowid, pRight, iHeight);
02000     if( iRowid==pCell->iRowid ){
02001       newCellIsRight = 1;
02002     }
02003     if( rc!=SQLITE_OK ){
02004       goto splitnode_out;
02005     }
02006   }
02007   if( pNode->iNode==1 ){
02008     for(i=0; i<NCELL(pLeft); i++){
02009       i64 iRowid = nodeGetRowid(pRtree, pLeft, i);
02010       rc = updateMapping(pRtree, iRowid, pLeft, iHeight);
02011       if( rc!=SQLITE_OK ){
02012         goto splitnode_out;
02013       }
02014     }
02015   }else if( newCellIsRight==0 ){
02016     rc = updateMapping(pRtree, pCell->iRowid, pLeft, iHeight);
02017   }
02018 
02019   if( rc==SQLITE_OK ){
02020     rc = nodeRelease(pRtree, pRight);
02021     pRight = 0;
02022   }
02023   if( rc==SQLITE_OK ){
02024     rc = nodeRelease(pRtree, pLeft);
02025     pLeft = 0;
02026   }
02027 
02028 splitnode_out:
02029   nodeRelease(pRtree, pRight);
02030   nodeRelease(pRtree, pLeft);
02031   sqlite3_free(aCell);
02032   return rc;
02033 }
02034 
02035 static int fixLeafParent(Rtree *pRtree, RtreeNode *pLeaf){
02036   int rc = SQLITE_OK;
02037   if( pLeaf->iNode!=1 && pLeaf->pParent==0 ){
02038     sqlite3_bind_int64(pRtree->pReadParent, 1, pLeaf->iNode);
02039     if( sqlite3_step(pRtree->pReadParent)==SQLITE_ROW ){
02040       i64 iNode = sqlite3_column_int64(pRtree->pReadParent, 0);
02041       rc = nodeAcquire(pRtree, iNode, 0, &pLeaf->pParent);
02042     }else{
02043       rc = SQLITE_ERROR;
02044     }
02045     sqlite3_reset(pRtree->pReadParent);
02046     if( rc==SQLITE_OK ){
02047       rc = fixLeafParent(pRtree, pLeaf->pParent);
02048     }
02049   }
02050   return rc;
02051 }
02052 
02053 static int deleteCell(Rtree *, RtreeNode *, int, int);
02054 
02055 static int removeNode(Rtree *pRtree, RtreeNode *pNode, int iHeight){
02056   int rc;
02057   RtreeNode *pParent;
02058   int iCell;
02059 
02060   assert( pNode->nRef==1 );
02061 
02062   /* Remove the entry in the parent cell. */
02063   iCell = nodeParentIndex(pRtree, pNode);
02064   pParent = pNode->pParent;
02065   pNode->pParent = 0;
02066   if( SQLITE_OK!=(rc = deleteCell(pRtree, pParent, iCell, iHeight+1)) 
02067    || SQLITE_OK!=(rc = nodeRelease(pRtree, pParent))
02068   ){
02069     return rc;
02070   }
02071 
02072   /* Remove the xxx_node entry. */
02073   sqlite3_bind_int64(pRtree->pDeleteNode, 1, pNode->iNode);
02074   sqlite3_step(pRtree->pDeleteNode);
02075   if( SQLITE_OK!=(rc = sqlite3_reset(pRtree->pDeleteNode)) ){
02076     return rc;
02077   }
02078 
02079   /* Remove the xxx_parent entry. */
02080   sqlite3_bind_int64(pRtree->pDeleteParent, 1, pNode->iNode);
02081   sqlite3_step(pRtree->pDeleteParent);
02082   if( SQLITE_OK!=(rc = sqlite3_reset(pRtree->pDeleteParent)) ){
02083     return rc;
02084   }
02085   
02086   /* Remove the node from the in-memory hash table and link it into
02087   ** the Rtree.pDeleted list. Its contents will be re-inserted later on.
02088   */
02089   nodeHashDelete(pRtree, pNode);
02090   pNode->iNode = iHeight;
02091   pNode->pNext = pRtree->pDeleted;
02092   pNode->nRef++;
02093   pRtree->pDeleted = pNode;
02094 
02095   return SQLITE_OK;
02096 }
02097 
02098 static void fixBoundingBox(Rtree *pRtree, RtreeNode *pNode){
02099   RtreeNode *pParent = pNode->pParent;
02100   if( pParent ){
02101     int ii; 
02102     int nCell = NCELL(pNode);
02103     RtreeCell box;                            /* Bounding box for pNode */
02104     nodeGetCell(pRtree, pNode, 0, &box);
02105     for(ii=1; ii<nCell; ii++){
02106       RtreeCell cell;
02107       nodeGetCell(pRtree, pNode, ii, &cell);
02108       cellUnion(pRtree, &box, &cell);
02109     }
02110     box.iRowid = pNode->iNode;
02111     ii = nodeParentIndex(pRtree, pNode);
02112     nodeOverwriteCell(pRtree, pParent, &box, ii);
02113     fixBoundingBox(pRtree, pParent);
02114   }
02115 }
02116 
02117 /*
02118 ** Delete the cell at index iCell of node pNode. After removing the
02119 ** cell, adjust the r-tree data structure if required.
02120 */
02121 static int deleteCell(Rtree *pRtree, RtreeNode *pNode, int iCell, int iHeight){
02122   int rc;
02123 
02124   if( SQLITE_OK!=(rc = fixLeafParent(pRtree, pNode)) ){
02125     return rc;
02126   }
02127 
02128   /* Remove the cell from the node. This call just moves bytes around
02129   ** the in-memory node image, so it cannot fail.
02130   */
02131   nodeDeleteCell(pRtree, pNode, iCell);
02132 
02133   /* If the node is not the tree root and now has less than the minimum
02134   ** number of cells, remove it from the tree. Otherwise, update the
02135   ** cell in the parent node so that it tightly contains the updated
02136   ** node.
02137   */
02138   if( pNode->iNode!=1 ){
02139     RtreeNode *pParent = pNode->pParent;
02140     if( (pParent->iNode!=1 || NCELL(pParent)!=1) 
02141      && (NCELL(pNode)<RTREE_MINCELLS(pRtree))
02142     ){
02143       rc = removeNode(pRtree, pNode, iHeight);
02144     }else{
02145       fixBoundingBox(pRtree, pNode);
02146     }
02147   }
02148 
02149   return rc;
02150 }
02151 
02152 static int Reinsert(
02153   Rtree *pRtree, 
02154   RtreeNode *pNode, 
02155   RtreeCell *pCell, 
02156   int iHeight
02157 ){
02158   int *aOrder;
02159   int *aSpare;
02160   RtreeCell *aCell;
02161   float *aDistance;
02162   int nCell;
02163   float aCenterCoord[RTREE_MAX_DIMENSIONS];
02164   int iDim;
02165   int ii;
02166   int rc = SQLITE_OK;
02167 
02168   memset(aCenterCoord, 0, sizeof(float)*RTREE_MAX_DIMENSIONS);
02169 
02170   nCell = NCELL(pNode)+1;
02171 
02172   /* Allocate the buffers used by this operation. The allocation is
02173   ** relinquished before this function returns.
02174   */
02175   aCell = (RtreeCell *)sqlite3_malloc(nCell * (
02176     sizeof(RtreeCell) +         /* aCell array */
02177     sizeof(int)       +         /* aOrder array */
02178     sizeof(int)       +         /* aSpare array */
02179     sizeof(float)               /* aDistance array */
02180   ));
02181   if( !aCell ){
02182     return SQLITE_NOMEM;
02183   }
02184   aOrder    = (int *)&aCell[nCell];
02185   aSpare    = (int *)&aOrder[nCell];
02186   aDistance = (float *)&aSpare[nCell];
02187 
02188   for(ii=0; ii<nCell; ii++){
02189     if( ii==(nCell-1) ){
02190       memcpy(&aCell[ii], pCell, sizeof(RtreeCell));
02191     }else{
02192       nodeGetCell(pRtree, pNode, ii, &aCell[ii]);
02193     }
02194     aOrder[ii] = ii;
02195     for(iDim=0; iDim<pRtree->nDim; iDim++){
02196       aCenterCoord[iDim] += DCOORD(aCell[ii].aCoord[iDim*2]);
02197       aCenterCoord[iDim] += DCOORD(aCell[ii].aCoord[iDim*2+1]);
02198     }
02199   }
02200   for(iDim=0; iDim<pRtree->nDim; iDim++){
02201     aCenterCoord[iDim] = aCenterCoord[iDim]/((float)nCell*2.0);
02202   }
02203 
02204   for(ii=0; ii<nCell; ii++){
02205     aDistance[ii] = 0.0;
02206     for(iDim=0; iDim<pRtree->nDim; iDim++){
02207       float coord = DCOORD(aCell[ii].aCoord[iDim*2+1]) - 
02208           DCOORD(aCell[ii].aCoord[iDim*2]);
02209       aDistance[ii] += (coord-aCenterCoord[iDim])*(coord-aCenterCoord[iDim]);
02210     }
02211   }
02212 
02213   SortByDistance(aOrder, nCell, aDistance, aSpare);
02214   nodeZero(pRtree, pNode);
02215 
02216   for(ii=0; rc==SQLITE_OK && ii<(nCell-(RTREE_MINCELLS(pRtree)+1)); ii++){
02217     RtreeCell *p = &aCell[aOrder[ii]];
02218     nodeInsertCell(pRtree, pNode, p);
02219     if( p->iRowid==pCell->iRowid ){
02220       if( iHeight==0 ){
02221         rc = rowidWrite(pRtree, p->iRowid, pNode->iNode);
02222       }else{
02223         rc = parentWrite(pRtree, p->iRowid, pNode->iNode);
02224       }
02225     }
02226   }
02227   if( rc==SQLITE_OK ){
02228     fixBoundingBox(pRtree, pNode);
02229   }
02230   for(; rc==SQLITE_OK && ii<nCell; ii++){
02231     /* Find a node to store this cell in. pNode->iNode currently contains
02232     ** the height of the sub-tree headed by the cell.
02233     */
02234     RtreeNode *pInsert;
02235     RtreeCell *p = &aCell[aOrder[ii]];
02236     rc = ChooseLeaf(pRtree, p, iHeight, &pInsert);
02237     if( rc==SQLITE_OK ){
02238       int rc2;
02239       rc = rtreeInsertCell(pRtree, pInsert, p, iHeight);
02240       rc2 = nodeRelease(pRtree, pInsert);
02241       if( rc==SQLITE_OK ){
02242         rc = rc2;
02243       }
02244     }
02245   }
02246 
02247   sqlite3_free(aCell);
02248   return rc;
02249 }
02250 
02251 /*
02252 ** Insert cell pCell into node pNode. Node pNode is the head of a 
02253 ** subtree iHeight high (leaf nodes have iHeight==0).
02254 */
02255 static int rtreeInsertCell(
02256   Rtree *pRtree,
02257   RtreeNode *pNode,
02258   RtreeCell *pCell,
02259   int iHeight
02260 ){
02261   int rc = SQLITE_OK;
02262   if( iHeight>0 ){
02263     RtreeNode *pChild = nodeHashLookup(pRtree, pCell->iRowid);
02264     if( pChild ){
02265       nodeRelease(pRtree, pChild->pParent);
02266       nodeReference(pNode);
02267       pChild->pParent = pNode;
02268     }
02269   }
02270   if( nodeInsertCell(pRtree, pNode, pCell) ){
02271 #if VARIANT_RSTARTREE_REINSERT
02272     if( iHeight<=pRtree->iReinsertHeight || pNode->iNode==1){
02273       rc = SplitNode(pRtree, pNode, pCell, iHeight);
02274     }else{
02275       pRtree->iReinsertHeight = iHeight;
02276       rc = Reinsert(pRtree, pNode, pCell, iHeight);
02277     }
02278 #else
02279     rc = SplitNode(pRtree, pNode, pCell, iHeight);
02280 #endif
02281   }else{
02282     AdjustTree(pRtree, pNode, pCell);
02283     if( iHeight==0 ){
02284       rc = rowidWrite(pRtree, pCell->iRowid, pNode->iNode);
02285     }else{
02286       rc = parentWrite(pRtree, pCell->iRowid, pNode->iNode);
02287     }
02288   }
02289   return rc;
02290 }
02291 
02292 static int reinsertNodeContent(Rtree *pRtree, RtreeNode *pNode){
02293   int ii;
02294   int rc = SQLITE_OK;
02295   int nCell = NCELL(pNode);
02296 
02297   for(ii=0; rc==SQLITE_OK && ii<nCell; ii++){
02298     RtreeNode *pInsert;
02299     RtreeCell cell;
02300     nodeGetCell(pRtree, pNode, ii, &cell);
02301 
02302     /* Find a node to store this cell in. pNode->iNode currently contains
02303     ** the height of the sub-tree headed by the cell.
02304     */
02305     rc = ChooseLeaf(pRtree, &cell, pNode->iNode, &pInsert);
02306     if( rc==SQLITE_OK ){
02307       int rc2;
02308       rc = rtreeInsertCell(pRtree, pInsert, &cell, pNode->iNode);
02309       rc2 = nodeRelease(pRtree, pInsert);
02310       if( rc==SQLITE_OK ){
02311         rc = rc2;
02312       }
02313     }
02314   }
02315   return rc;
02316 }
02317 
02318 /*
02319 ** Select a currently unused rowid for a new r-tree record.
02320 */
02321 static int newRowid(Rtree *pRtree, i64 *piRowid){
02322   int rc;
02323   sqlite3_bind_null(pRtree->pWriteRowid, 1);
02324   sqlite3_bind_null(pRtree->pWriteRowid, 2);
02325   sqlite3_step(pRtree->pWriteRowid);
02326   rc = sqlite3_reset(pRtree->pWriteRowid);
02327   *piRowid = sqlite3_last_insert_rowid(pRtree->db);
02328   return rc;
02329 }
02330 
02331 #ifndef NDEBUG
02332 static int hashIsEmpty(Rtree *pRtree){
02333   int ii;
02334   for(ii=0; ii<HASHSIZE; ii++){
02335     assert( !pRtree->aHash[ii] );
02336   }
02337   return 1;
02338 }
02339 #endif
02340 
02341 /*
02342 ** The xUpdate method for rtree module virtual tables.
02343 */
02344 int rtreeUpdate(
02345   sqlite3_vtab *pVtab, 
02346   int nData, 
02347   sqlite3_value **azData, 
02348   sqlite_int64 *pRowid
02349 ){
02350   Rtree *pRtree = (Rtree *)pVtab;
02351   int rc = SQLITE_OK;
02352 
02353   rtreeReference(pRtree);
02354 
02355   assert(nData>=1);
02356   assert(hashIsEmpty(pRtree));
02357 
02358   /* If azData[0] is not an SQL NULL value, it is the rowid of a
02359   ** record to delete from the r-tree table. The following block does
02360   ** just that.
02361   */
02362   if( sqlite3_value_type(azData[0])!=SQLITE_NULL ){
02363     i64 iDelete;                /* The rowid to delete */
02364     RtreeNode *pLeaf;           /* Leaf node containing record iDelete */
02365     int iCell;                  /* Index of iDelete cell in pLeaf */
02366     RtreeNode *pRoot;
02367 
02368     /* Obtain a reference to the root node to initialise Rtree.iDepth */
02369     rc = nodeAcquire(pRtree, 1, 0, &pRoot);
02370 
02371     /* Obtain a reference to the leaf node that contains the entry 
02372     ** about to be deleted. 
02373     */
02374     if( rc==SQLITE_OK ){
02375       iDelete = sqlite3_value_int64(azData[0]);
02376       rc = findLeafNode(pRtree, iDelete, &pLeaf);
02377     }
02378 
02379     /* Delete the cell in question from the leaf node. */
02380     if( rc==SQLITE_OK ){
02381       int rc2;
02382       iCell = nodeRowidIndex(pRtree, pLeaf, iDelete);
02383       rc = deleteCell(pRtree, pLeaf, iCell, 0);
02384       rc2 = nodeRelease(pRtree, pLeaf);
02385       if( rc==SQLITE_OK ){
02386         rc = rc2;
02387       }
02388     }
02389 
02390     /* Delete the corresponding entry in the <rtree>_rowid table. */
02391     if( rc==SQLITE_OK ){
02392       sqlite3_bind_int64(pRtree->pDeleteRowid, 1, iDelete);
02393       sqlite3_step(pRtree->pDeleteRowid);
02394       rc = sqlite3_reset(pRtree->pDeleteRowid);
02395     }
02396 
02397     /* Check if the root node now has exactly one child. If so, remove
02398     ** it, schedule the contents of the child for reinsertion and 
02399     ** reduce the tree height by one.
02400     **
02401     ** This is equivalent to copying the contents of the child into
02402     ** the root node (the operation that Gutman's paper says to perform 
02403     ** in this scenario).
02404     */
02405     if( rc==SQLITE_OK && pRtree->iDepth>0 ){
02406       if( rc==SQLITE_OK && NCELL(pRoot)==1 ){
02407         RtreeNode *pChild;
02408         i64 iChild = nodeGetRowid(pRtree, pRoot, 0);
02409         rc = nodeAcquire(pRtree, iChild, pRoot, &pChild);
02410         if( rc==SQLITE_OK ){
02411           rc = removeNode(pRtree, pChild, pRtree->iDepth-1);
02412         }
02413         if( rc==SQLITE_OK ){
02414           pRtree->iDepth--;
02415           writeInt16(pRoot->zData, pRtree->iDepth);
02416           pRoot->isDirty = 1;
02417         }
02418       }
02419     }
02420 
02421     /* Re-insert the contents of any underfull nodes removed from the tree. */
02422     for(pLeaf=pRtree->pDeleted; pLeaf; pLeaf=pRtree->pDeleted){
02423       if( rc==SQLITE_OK ){
02424         rc = reinsertNodeContent(pRtree, pLeaf);
02425       }
02426       pRtree->pDeleted = pLeaf->pNext;
02427       sqlite3_free(pLeaf);
02428     }
02429 
02430     /* Release the reference to the root node. */
02431     if( rc==SQLITE_OK ){
02432       rc = nodeRelease(pRtree, pRoot);
02433     }else{
02434       nodeRelease(pRtree, pRoot);
02435     }
02436   }
02437 
02438   /* If the azData[] array contains more than one element, elements
02439   ** (azData[2]..azData[argc-1]) contain a new record to insert into
02440   ** the r-tree structure.
02441   */
02442   if( rc==SQLITE_OK && nData>1 ){
02443     /* Insert a new record into the r-tree */
02444     RtreeCell cell;
02445     int ii;
02446     RtreeNode *pLeaf;
02447 
02448     /* Populate the cell.aCoord[] array. The first coordinate is azData[3]. */
02449     assert( nData==(pRtree->nDim*2 + 3) );
02450     if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
02451       for(ii=0; ii<(pRtree->nDim*2); ii+=2){
02452         cell.aCoord[ii].f = (float)sqlite3_value_double(azData[ii+3]);
02453         cell.aCoord[ii+1].f = (float)sqlite3_value_double(azData[ii+4]);
02454         if( cell.aCoord[ii].f>cell.aCoord[ii+1].f ){
02455           rc = SQLITE_CONSTRAINT;
02456           goto constraint;
02457         }
02458       }
02459     }else{
02460       for(ii=0; ii<(pRtree->nDim*2); ii+=2){
02461         cell.aCoord[ii].i = sqlite3_value_int(azData[ii+3]);
02462         cell.aCoord[ii+1].i = sqlite3_value_int(azData[ii+4]);
02463         if( cell.aCoord[ii].i>cell.aCoord[ii+1].i ){
02464           rc = SQLITE_CONSTRAINT;
02465           goto constraint;
02466         }
02467       }
02468     }
02469 
02470     /* Figure out the rowid of the new row. */
02471     if( sqlite3_value_type(azData[2])==SQLITE_NULL ){
02472       rc = newRowid(pRtree, &cell.iRowid);
02473     }else{
02474       cell.iRowid = sqlite3_value_int64(azData[2]);
02475       sqlite3_bind_int64(pRtree->pReadRowid, 1, cell.iRowid);
02476       if( SQLITE_ROW==sqlite3_step(pRtree->pReadRowid) ){
02477         sqlite3_reset(pRtree->pReadRowid);
02478         rc = SQLITE_CONSTRAINT;
02479         goto constraint;
02480       }
02481       rc = sqlite3_reset(pRtree->pReadRowid);
02482     }
02483 
02484     if( rc==SQLITE_OK ){
02485       rc = ChooseLeaf(pRtree, &cell, 0, &pLeaf);
02486     }
02487     if( rc==SQLITE_OK ){
02488       int rc2;
02489       pRtree->iReinsertHeight = -1;
02490       rc = rtreeInsertCell(pRtree, pLeaf, &cell, 0);
02491       rc2 = nodeRelease(pRtree, pLeaf);
02492       if( rc==SQLITE_OK ){
02493         rc = rc2;
02494       }
02495     }
02496   }
02497 
02498 constraint:
02499   rtreeRelease(pRtree);
02500   return rc;
02501 }
02502 
02503 /*
02504 ** The xRename method for rtree module virtual tables.
02505 */
02506 static int rtreeRename(sqlite3_vtab *pVtab, const char *zNewName){
02507   Rtree *pRtree = (Rtree *)pVtab;
02508   int rc = SQLITE_NOMEM;
02509   char *zSql = sqlite3_mprintf(
02510     "ALTER TABLE %Q.'%q_node'   RENAME TO \"%w_node\";"
02511     "ALTER TABLE %Q.'%q_parent' RENAME TO \"%w_parent\";"
02512     "ALTER TABLE %Q.'%q_rowid'  RENAME TO \"%w_rowid\";"
02513     , pRtree->zDb, pRtree->zName, zNewName 
02514     , pRtree->zDb, pRtree->zName, zNewName 
02515     , pRtree->zDb, pRtree->zName, zNewName
02516   );
02517   if( zSql ){
02518     rc = sqlite3_exec(pRtree->db, zSql, 0, 0, 0);
02519     sqlite3_free(zSql);
02520   }
02521   return rc;
02522 }
02523 
02524 static sqlite3_module rtreeModule = {
02525   0,                         /* iVersion */
02526   rtreeCreate,                /* xCreate - create a table */
02527   rtreeConnect,               /* xConnect - connect to an existing table */
02528   rtreeBestIndex,             /* xBestIndex - Determine search strategy */
02529   rtreeDisconnect,            /* xDisconnect - Disconnect from a table */
02530   rtreeDestroy,               /* xDestroy - Drop a table */
02531   rtreeOpen,                  /* xOpen - open a cursor */
02532   rtreeClose,                 /* xClose - close a cursor */
02533   rtreeFilter,                /* xFilter - configure scan constraints */
02534   rtreeNext,                  /* xNext - advance a cursor */
02535   rtreeEof,                   /* xEof */
02536   rtreeColumn,                /* xColumn - read data */
02537   rtreeRowid,                 /* xRowid - read data */
02538   rtreeUpdate,                /* xUpdate - write data */
02539   0,                          /* xBegin - begin transaction */
02540   0,                          /* xSync - sync transaction */
02541   0,                          /* xCommit - commit transaction */
02542   0,                          /* xRollback - rollback transaction */
02543   0,                          /* xFindFunction - function overloading */
02544   rtreeRename                 /* xRename - rename the table */
02545 };
02546 
02547 static int rtreeSqlInit(
02548   Rtree *pRtree, 
02549   sqlite3 *db, 
02550   const char *zDb, 
02551   const char *zPrefix, 
02552   int isCreate
02553 ){
02554   int rc = SQLITE_OK;
02555 
02556   #define N_STATEMENT 9
02557   static const char *azSql[N_STATEMENT] = {
02558     /* Read and write the xxx_node table */
02559     "SELECT data FROM '%q'.'%q_node' WHERE nodeno = :1",
02560     "INSERT OR REPLACE INTO '%q'.'%q_node' VALUES(:1, :2)",
02561     "DELETE FROM '%q'.'%q_node' WHERE nodeno = :1",
02562 
02563     /* Read and write the xxx_rowid table */
02564     "SELECT nodeno FROM '%q'.'%q_rowid' WHERE rowid = :1",
02565     "INSERT OR REPLACE INTO '%q'.'%q_rowid' VALUES(:1, :2)",
02566     "DELETE FROM '%q'.'%q_rowid' WHERE rowid = :1",
02567 
02568     /* Read and write the xxx_parent table */
02569     "SELECT parentnode FROM '%q'.'%q_parent' WHERE nodeno = :1",
02570     "INSERT OR REPLACE INTO '%q'.'%q_parent' VALUES(:1, :2)",
02571     "DELETE FROM '%q'.'%q_parent' WHERE nodeno = :1"
02572   };
02573   sqlite3_stmt **appStmt[N_STATEMENT];
02574   int i;
02575 
02576   pRtree->db = db;
02577 
02578   if( isCreate ){
02579     char *zCreate = sqlite3_mprintf(
02580 "CREATE TABLE \"%w\".\"%w_node\"(nodeno INTEGER PRIMARY KEY, data BLOB);"
02581 "CREATE TABLE \"%w\".\"%w_rowid\"(rowid INTEGER PRIMARY KEY, nodeno INTEGER);"
02582 "CREATE TABLE \"%w\".\"%w_parent\"(nodeno INTEGER PRIMARY KEY, parentnode INTEGER);"
02583 "INSERT INTO '%q'.'%q_node' VALUES(1, zeroblob(%d))",
02584       zDb, zPrefix, zDb, zPrefix, zDb, zPrefix, zDb, zPrefix, pRtree->iNodeSize
02585     );
02586     if( !zCreate ){
02587       return SQLITE_NOMEM;
02588     }
02589     rc = sqlite3_exec(db, zCreate, 0, 0, 0);
02590     sqlite3_free(zCreate);
02591     if( rc!=SQLITE_OK ){
02592       return rc;
02593     }
02594   }
02595 
02596   appStmt[0] = &pRtree->pReadNode;
02597   appStmt[1] = &pRtree->pWriteNode;
02598   appStmt[2] = &pRtree->pDeleteNode;
02599   appStmt[3] = &pRtree->pReadRowid;
02600   appStmt[4] = &pRtree->pWriteRowid;
02601   appStmt[5] = &pRtree->pDeleteRowid;
02602   appStmt[6] = &pRtree->pReadParent;
02603   appStmt[7] = &pRtree->pWriteParent;
02604   appStmt[8] = &pRtree->pDeleteParent;
02605 
02606   for(i=0; i<N_STATEMENT && rc==SQLITE_OK; i++){
02607     char *zSql = sqlite3_mprintf(azSql[i], zDb, zPrefix);
02608     if( zSql ){
02609       rc = sqlite3_prepare_v2(db, zSql, -1, appStmt[i], 0); 
02610     }else{
02611       rc = SQLITE_NOMEM;
02612     }
02613     sqlite3_free(zSql);
02614   }
02615 
02616   return rc;
02617 }
02618 
02619 /*
02620 ** This routine queries database handle db for the page-size used by
02621 ** database zDb. If successful, the page-size in bytes is written to
02622 ** *piPageSize and SQLITE_OK returned. Otherwise, and an SQLite error 
02623 ** code is returned.
02624 */
02625 static int getPageSize(sqlite3 *db, const char *zDb, int *piPageSize){
02626   int rc = SQLITE_NOMEM;
02627   char *zSql;
02628   sqlite3_stmt *pStmt = 0;
02629 
02630   zSql = sqlite3_mprintf("PRAGMA %Q.page_size", zDb);
02631   if( !zSql ){
02632     return SQLITE_NOMEM;
02633   }
02634 
02635   rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
02636   sqlite3_free(zSql);
02637   if( rc!=SQLITE_OK ){
02638     return rc;
02639   }
02640 
02641   if( SQLITE_ROW==sqlite3_step(pStmt) ){
02642     *piPageSize = sqlite3_column_int(pStmt, 0);
02643   }
02644   return sqlite3_finalize(pStmt);
02645 }
02646 
02647 /* 
02648 ** This function is the implementation of both the xConnect and xCreate
02649 ** methods of the r-tree virtual table.
02650 **
02651 **   argv[0]   -> module name
02652 **   argv[1]   -> database name
02653 **   argv[2]   -> table name
02654 **   argv[...] -> column names...
02655 */
02656 static int rtreeInit(
02657   sqlite3 *db,                        /* Database connection */
02658   void *pAux,                         /* One of the RTREE_COORD_* constants */
02659   int argc, const char *const*argv,   /* Parameters to CREATE TABLE statement */
02660   sqlite3_vtab **ppVtab,              /* OUT: New virtual table */
02661   char **pzErr,                       /* OUT: Error message, if any */
02662   int isCreate                        /* True for xCreate, false for xConnect */
02663 ){
02664   int rc = SQLITE_OK;
02665   int iPageSize = 0;
02666   Rtree *pRtree;
02667   int nDb;              /* Length of string argv[1] */
02668   int nName;            /* Length of string argv[2] */
02669   int eCoordType = (int)pAux;
02670 
02671   const char *aErrMsg[] = {
02672     0,                                                    /* 0 */
02673     "Wrong number of columns for an rtree table",         /* 1 */
02674     "Too few columns for an rtree table",                 /* 2 */
02675     "Too many columns for an rtree table"                 /* 3 */
02676   };
02677 
02678   int iErr = (argc<6) ? 2 : argc>(RTREE_MAX_DIMENSIONS*2+4) ? 3 : argc%2;
02679   if( aErrMsg[iErr] ){
02680     *pzErr = sqlite3_mprintf("%s", aErrMsg[iErr]);
02681     return SQLITE_ERROR;
02682   }
02683 
02684   rc = getPageSize(db, argv[1], &iPageSize);
02685   if( rc!=SQLITE_OK ){
02686     return rc;
02687   }
02688 
02689   /* Allocate the sqlite3_vtab structure */
02690   nDb = strlen(argv[1]);
02691   nName = strlen(argv[2]);
02692   pRtree = (Rtree *)sqlite3_malloc(sizeof(Rtree)+nDb+nName+2);
02693   if( !pRtree ){
02694     return SQLITE_NOMEM;
02695   }
02696   memset(pRtree, 0, sizeof(Rtree)+nDb+nName+2);
02697   pRtree->nBusy = 1;
02698   pRtree->base.pModule = &rtreeModule;
02699   pRtree->zDb = (char *)&pRtree[1];
02700   pRtree->zName = &pRtree->zDb[nDb+1];
02701   pRtree->nDim = (argc-4)/2;
02702   pRtree->nBytesPerCell = 8 + pRtree->nDim*4*2;
02703   pRtree->eCoordType = eCoordType;
02704   memcpy(pRtree->zDb, argv[1], nDb);
02705   memcpy(pRtree->zName, argv[2], nName);
02706 
02707   /* Figure out the node size to use. By default, use 64 bytes less than
02708   ** the database page-size. This ensures that each node is stored on
02709   ** a single database page.
02710   **
02711   ** If the databasd page-size is so large that more than RTREE_MAXCELLS
02712   ** entries would fit in a single node, use a smaller node-size.
02713   */
02714   pRtree->iNodeSize = iPageSize-64;
02715   if( (4+pRtree->nBytesPerCell*RTREE_MAXCELLS)<pRtree->iNodeSize ){
02716     pRtree->iNodeSize = 4+pRtree->nBytesPerCell*RTREE_MAXCELLS;
02717   }
02718 
02719   /* Create/Connect to the underlying relational database schema. If
02720   ** that is successful, call sqlite3_declare_vtab() to configure
02721   ** the r-tree table schema.
02722   */
02723   if( (rc = rtreeSqlInit(pRtree, db, argv[1], argv[2], isCreate)) ){
02724     *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
02725   }else{
02726     char *zSql = sqlite3_mprintf("CREATE TABLE x(%s", argv[3]);
02727     char *zTmp;
02728     int ii;
02729     for(ii=4; zSql && ii<argc; ii++){
02730       zTmp = zSql;
02731       zSql = sqlite3_mprintf("%s, %s", zTmp, argv[ii]);
02732       sqlite3_free(zTmp);
02733     }
02734     if( zSql ){
02735       zTmp = zSql;
02736       zSql = sqlite3_mprintf("%s);", zTmp);
02737       sqlite3_free(zTmp);
02738     }
02739     if( !zSql || sqlite3_declare_vtab(db, zSql) ){
02740       rc = SQLITE_NOMEM;
02741     }
02742     sqlite3_free(zSql);
02743   }
02744 
02745   if( rc==SQLITE_OK ){
02746     *ppVtab = (sqlite3_vtab *)pRtree;
02747   }else{
02748     rtreeRelease(pRtree);
02749   }
02750   return rc;
02751 }
02752 
02753 
02754 /*
02755 ** Implementation of a scalar function that decodes r-tree nodes to
02756 ** human readable strings. This can be used for debugging and analysis.
02757 **
02758 ** The scalar function takes two arguments, a blob of data containing
02759 ** an r-tree node, and the number of dimensions the r-tree indexes.
02760 ** For a two-dimensional r-tree structure called "rt", to deserialize
02761 ** all nodes, a statement like:
02762 **
02763 **   SELECT rtreenode(2, data) FROM rt_node;
02764 **
02765 ** The human readable string takes the form of a Tcl list with one
02766 ** entry for each cell in the r-tree node. Each entry is itself a
02767 ** list, containing the 8-byte rowid/pageno followed by the 
02768 ** <num-dimension>*2 coordinates.
02769 */
02770 static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){
02771   char *zText = 0;
02772   RtreeNode node;
02773   Rtree tree;
02774   int ii;
02775 
02776   memset(&node, 0, sizeof(RtreeNode));
02777   memset(&tree, 0, sizeof(Rtree));
02778   tree.nDim = sqlite3_value_int(apArg[0]);
02779   tree.nBytesPerCell = 8 + 8 * tree.nDim;
02780   node.zData = (u8 *)sqlite3_value_blob(apArg[1]);
02781 
02782   for(ii=0; ii<NCELL(&node); ii++){
02783     char zCell[512];
02784     int nCell = 0;
02785     RtreeCell cell;
02786     int jj;
02787 
02788     nodeGetCell(&tree, &node, ii, &cell);
02789     sqlite3_snprintf(512-nCell,&zCell[nCell],"%d", cell.iRowid);
02790     nCell = strlen(zCell);
02791     for(jj=0; jj<tree.nDim*2; jj++){
02792       sqlite3_snprintf(512-nCell,&zCell[nCell]," %f",(double)cell.aCoord[jj].f);
02793       nCell = strlen(zCell);
02794     }
02795 
02796     if( zText ){
02797       char *zTextNew = sqlite3_mprintf("%s {%s}", zText, zCell);
02798       sqlite3_free(zText);
02799       zText = zTextNew;
02800     }else{
02801       zText = sqlite3_mprintf("{%s}", zCell);
02802     }
02803   }
02804   
02805   sqlite3_result_text(ctx, zText, -1, sqlite3_free);
02806 }
02807 
02808 static void rtreedepth(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){
02809   if( sqlite3_value_type(apArg[0])!=SQLITE_BLOB 
02810    || sqlite3_value_bytes(apArg[0])<2
02811   ){
02812     sqlite3_result_error(ctx, "Invalid argument to rtreedepth()", -1); 
02813   }else{
02814     u8 *zBlob = (u8 *)sqlite3_value_blob(apArg[0]);
02815     sqlite3_result_int(ctx, readInt16(zBlob));
02816   }
02817 }
02818 
02819 /*
02820 ** Register the r-tree module with database handle db. This creates the
02821 ** virtual table module "rtree" and the debugging/analysis scalar 
02822 ** function "rtreenode".
02823 */
02824 int sqlite3RtreeInit(sqlite3 *db){
02825   int rc = SQLITE_OK;
02826 
02827   if( rc==SQLITE_OK ){
02828     int utf8 = SQLITE_UTF8;
02829     rc = sqlite3_create_function(db, "rtreenode", 2, utf8, 0, rtreenode, 0, 0);
02830   }
02831   if( rc==SQLITE_OK ){
02832     int utf8 = SQLITE_UTF8;
02833     rc = sqlite3_create_function(db, "rtreedepth", 1, utf8, 0,rtreedepth, 0, 0);
02834   }
02835   if( rc==SQLITE_OK ){
02836     void *c = (void *)RTREE_COORD_REAL32;
02837     rc = sqlite3_create_module_v2(db, "rtree", &rtreeModule, c, 0);
02838   }
02839   if( rc==SQLITE_OK ){
02840     void *c = (void *)RTREE_COORD_INT32;
02841     rc = sqlite3_create_module_v2(db, "rtree_i32", &rtreeModule, c, 0);
02842   }
02843 
02844   return rc;
02845 }
02846 
02847 #if !SQLITE_CORE
02848 int sqlite3_extension_init(
02849   sqlite3 *db,
02850   char **pzErrMsg,
02851   const sqlite3_api_routines *pApi
02852 ){
02853   SQLITE_EXTENSION_INIT2(pApi)
02854   return sqlite3RtreeInit(db);
02855 }
02856 #endif
02857 
02858 #endif

ContextLogger2—ContextLogger2 Logger Daemon Internals—Generated on Mon May 2 13:49:56 2011 by Doxygen 1.6.1