| OLD | NEW | 
 | (Empty) | 
|     1 /* |  | 
|     2 ** 2001 September 15 |  | 
|     3 ** |  | 
|     4 ** The author disclaims copyright to this source code.  In place of |  | 
|     5 ** a legal notice, here is a blessing: |  | 
|     6 ** |  | 
|     7 **    May you do good and not evil. |  | 
|     8 **    May you find forgiveness for yourself and forgive others. |  | 
|     9 **    May you share freely, never taking more than you give. |  | 
|    10 ** |  | 
|    11 ************************************************************************* |  | 
|    12 ** This file contains code for implementations of the r-tree and r*-tree |  | 
|    13 ** algorithms packaged as an SQLite virtual table module. |  | 
|    14 ** |  | 
|    15 ** $Id: rtree.c,v 1.14 2009/08/06 18:36:47 danielk1977 Exp $ |  | 
|    16 */ |  | 
|    17  |  | 
|    18 #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RTREE) |  | 
|    19  |  | 
|    20 /* |  | 
|    21 ** This file contains an implementation of a couple of different variants |  | 
|    22 ** of the r-tree algorithm. See the README file for further details. The  |  | 
|    23 ** same data-structure is used for all, but the algorithms for insert and |  | 
|    24 ** delete operations vary. The variants used are selected at compile time  |  | 
|    25 ** by defining the following symbols: |  | 
|    26 */ |  | 
|    27  |  | 
|    28 /* Either, both or none of the following may be set to activate  |  | 
|    29 ** r*tree variant algorithms. |  | 
|    30 */ |  | 
|    31 #define VARIANT_RSTARTREE_CHOOSESUBTREE 0 |  | 
|    32 #define VARIANT_RSTARTREE_REINSERT      1 |  | 
|    33  |  | 
|    34 /*  |  | 
|    35 ** Exactly one of the following must be set to 1. |  | 
|    36 */ |  | 
|    37 #define VARIANT_GUTTMAN_QUADRATIC_SPLIT 0 |  | 
|    38 #define VARIANT_GUTTMAN_LINEAR_SPLIT    0 |  | 
|    39 #define VARIANT_RSTARTREE_SPLIT         1 |  | 
|    40  |  | 
|    41 #define VARIANT_GUTTMAN_SPLIT \ |  | 
|    42         (VARIANT_GUTTMAN_LINEAR_SPLIT||VARIANT_GUTTMAN_QUADRATIC_SPLIT) |  | 
|    43  |  | 
|    44 #if VARIANT_GUTTMAN_QUADRATIC_SPLIT |  | 
|    45   #define PickNext QuadraticPickNext |  | 
|    46   #define PickSeeds QuadraticPickSeeds |  | 
|    47   #define AssignCells splitNodeGuttman |  | 
|    48 #endif |  | 
|    49 #if VARIANT_GUTTMAN_LINEAR_SPLIT |  | 
|    50   #define PickNext LinearPickNext |  | 
|    51   #define PickSeeds LinearPickSeeds |  | 
|    52   #define AssignCells splitNodeGuttman |  | 
|    53 #endif |  | 
|    54 #if VARIANT_RSTARTREE_SPLIT |  | 
|    55   #define AssignCells splitNodeStartree |  | 
|    56 #endif |  | 
|    57  |  | 
|    58  |  | 
|    59 #ifndef SQLITE_CORE |  | 
|    60   #include "sqlite3ext.h" |  | 
|    61   SQLITE_EXTENSION_INIT1 |  | 
|    62 #else |  | 
|    63   #include "sqlite3.h" |  | 
|    64 #endif |  | 
|    65  |  | 
|    66 #include <string.h> |  | 
|    67 #include <assert.h> |  | 
|    68  |  | 
|    69 #ifndef SQLITE_AMALGAMATION |  | 
|    70 typedef sqlite3_int64 i64; |  | 
|    71 typedef unsigned char u8; |  | 
|    72 typedef unsigned int u32; |  | 
|    73 #endif |  | 
|    74  |  | 
|    75 typedef struct Rtree Rtree; |  | 
|    76 typedef struct RtreeCursor RtreeCursor; |  | 
|    77 typedef struct RtreeNode RtreeNode; |  | 
|    78 typedef struct RtreeCell RtreeCell; |  | 
|    79 typedef struct RtreeConstraint RtreeConstraint; |  | 
|    80 typedef union RtreeCoord RtreeCoord; |  | 
|    81  |  | 
|    82 /* The rtree may have between 1 and RTREE_MAX_DIMENSIONS dimensions. */ |  | 
|    83 #define RTREE_MAX_DIMENSIONS 5 |  | 
|    84  |  | 
|    85 /* Size of hash table Rtree.aHash. This hash table is not expected to |  | 
|    86 ** ever contain very many entries, so a fixed number of buckets is  |  | 
|    87 ** used. |  | 
|    88 */ |  | 
|    89 #define HASHSIZE 128 |  | 
|    90  |  | 
|    91 /*  |  | 
|    92 ** An rtree virtual-table object. |  | 
|    93 */ |  | 
|    94 struct Rtree { |  | 
|    95   sqlite3_vtab base; |  | 
|    96   sqlite3 *db;                /* Host database connection */ |  | 
|    97   int iNodeSize;              /* Size in bytes of each node in the node table */ |  | 
|    98   int nDim;                   /* Number of dimensions */ |  | 
|    99   int nBytesPerCell;          /* Bytes consumed per cell */ |  | 
|   100   int iDepth;                 /* Current depth of the r-tree structure */ |  | 
|   101   char *zDb;                  /* Name of database containing r-tree table */ |  | 
|   102   char *zName;                /* Name of r-tree table */  |  | 
|   103   RtreeNode *aHash[HASHSIZE]; /* Hash table of in-memory nodes. */  |  | 
|   104   int nBusy;                  /* Current number of users of this structure */ |  | 
|   105  |  | 
|   106   /* List of nodes removed during a CondenseTree operation. List is |  | 
|   107   ** linked together via the pointer normally used for hash chains - |  | 
|   108   ** RtreeNode.pNext. RtreeNode.iNode stores the depth of the sub-tree  |  | 
|   109   ** headed by the node (leaf nodes have RtreeNode.iNode==0). |  | 
|   110   */ |  | 
|   111   RtreeNode *pDeleted; |  | 
|   112   int iReinsertHeight;        /* Height of sub-trees Reinsert() has run on */ |  | 
|   113  |  | 
|   114   /* Statements to read/write/delete a record from xxx_node */ |  | 
|   115   sqlite3_stmt *pReadNode; |  | 
|   116   sqlite3_stmt *pWriteNode; |  | 
|   117   sqlite3_stmt *pDeleteNode; |  | 
|   118  |  | 
|   119   /* Statements to read/write/delete a record from xxx_rowid */ |  | 
|   120   sqlite3_stmt *pReadRowid; |  | 
|   121   sqlite3_stmt *pWriteRowid; |  | 
|   122   sqlite3_stmt *pDeleteRowid; |  | 
|   123  |  | 
|   124   /* Statements to read/write/delete a record from xxx_parent */ |  | 
|   125   sqlite3_stmt *pReadParent; |  | 
|   126   sqlite3_stmt *pWriteParent; |  | 
|   127   sqlite3_stmt *pDeleteParent; |  | 
|   128  |  | 
|   129   int eCoordType; |  | 
|   130 }; |  | 
|   131  |  | 
|   132 /* Possible values for eCoordType: */ |  | 
|   133 #define RTREE_COORD_REAL32 0 |  | 
|   134 #define RTREE_COORD_INT32  1 |  | 
|   135  |  | 
|   136 /* |  | 
|   137 ** The minimum number of cells allowed for a node is a third of the  |  | 
|   138 ** maximum. In Gutman's notation: |  | 
|   139 ** |  | 
|   140 **     m = M/3 |  | 
|   141 ** |  | 
|   142 ** If an R*-tree "Reinsert" operation is required, the same number of |  | 
|   143 ** cells are removed from the overfull node and reinserted into the tree. |  | 
|   144 */ |  | 
|   145 #define RTREE_MINCELLS(p) ((((p)->iNodeSize-4)/(p)->nBytesPerCell)/3) |  | 
|   146 #define RTREE_REINSERT(p) RTREE_MINCELLS(p) |  | 
|   147 #define RTREE_MAXCELLS 51 |  | 
|   148  |  | 
|   149 /*  |  | 
|   150 ** An rtree cursor object. |  | 
|   151 */ |  | 
|   152 struct RtreeCursor { |  | 
|   153   sqlite3_vtab_cursor base; |  | 
|   154   RtreeNode *pNode;                 /* Node cursor is currently pointing at */ |  | 
|   155   int iCell;                        /* Index of current cell in pNode */ |  | 
|   156   int iStrategy;                    /* Copy of idxNum search parameter */ |  | 
|   157   int nConstraint;                  /* Number of entries in aConstraint */ |  | 
|   158   RtreeConstraint *aConstraint;     /* Search constraints. */ |  | 
|   159 }; |  | 
|   160  |  | 
|   161 union RtreeCoord { |  | 
|   162   float f; |  | 
|   163   int i; |  | 
|   164 }; |  | 
|   165  |  | 
|   166 /* |  | 
|   167 ** The argument is an RtreeCoord. Return the value stored within the RtreeCoord |  | 
|   168 ** formatted as a double. This macro assumes that local variable pRtree points |  | 
|   169 ** to the Rtree structure associated with the RtreeCoord. |  | 
|   170 */ |  | 
|   171 #define DCOORD(coord) (                           \ |  | 
|   172   (pRtree->eCoordType==RTREE_COORD_REAL32) ?      \ |  | 
|   173     ((double)coord.f) :                           \ |  | 
|   174     ((double)coord.i)                             \ |  | 
|   175 ) |  | 
|   176  |  | 
|   177 /* |  | 
|   178 ** A search constraint. |  | 
|   179 */ |  | 
|   180 struct RtreeConstraint { |  | 
|   181   int iCoord;                       /* Index of constrained coordinate */ |  | 
|   182   int op;                           /* Constraining operation */ |  | 
|   183   double rValue;                    /* Constraint value. */ |  | 
|   184 }; |  | 
|   185  |  | 
|   186 /* Possible values for RtreeConstraint.op */ |  | 
|   187 #define RTREE_EQ 0x41 |  | 
|   188 #define RTREE_LE 0x42 |  | 
|   189 #define RTREE_LT 0x43 |  | 
|   190 #define RTREE_GE 0x44 |  | 
|   191 #define RTREE_GT 0x45 |  | 
|   192  |  | 
|   193 /*  |  | 
|   194 ** An rtree structure node. |  | 
|   195 ** |  | 
|   196 ** Data format (RtreeNode.zData): |  | 
|   197 ** |  | 
|   198 **   1. If the node is the root node (node 1), then the first 2 bytes |  | 
|   199 **      of the node contain the tree depth as a big-endian integer. |  | 
|   200 **      For non-root nodes, the first 2 bytes are left unused. |  | 
|   201 ** |  | 
|   202 **   2. The next 2 bytes contain the number of entries currently  |  | 
|   203 **      stored in the node. |  | 
|   204 ** |  | 
|   205 **   3. The remainder of the node contains the node entries. Each entry |  | 
|   206 **      consists of a single 8-byte integer followed by an even number |  | 
|   207 **      of 4-byte coordinates. For leaf nodes the integer is the rowid |  | 
|   208 **      of a record. For internal nodes it is the node number of a |  | 
|   209 **      child page. |  | 
|   210 */ |  | 
|   211 struct RtreeNode { |  | 
|   212   RtreeNode *pParent;               /* Parent node */ |  | 
|   213   i64 iNode; |  | 
|   214   int nRef; |  | 
|   215   int isDirty; |  | 
|   216   u8 *zData; |  | 
|   217   RtreeNode *pNext;                 /* Next node in this hash chain */ |  | 
|   218 }; |  | 
|   219 #define NCELL(pNode) readInt16(&(pNode)->zData[2]) |  | 
|   220  |  | 
|   221 /*  |  | 
|   222 ** Structure to store a deserialized rtree record. |  | 
|   223 */ |  | 
|   224 struct RtreeCell { |  | 
|   225   i64 iRowid; |  | 
|   226   RtreeCoord aCoord[RTREE_MAX_DIMENSIONS*2]; |  | 
|   227 }; |  | 
|   228  |  | 
|   229 #ifndef MAX |  | 
|   230 # define MAX(x,y) ((x) < (y) ? (y) : (x)) |  | 
|   231 #endif |  | 
|   232 #ifndef MIN |  | 
|   233 # define MIN(x,y) ((x) > (y) ? (y) : (x)) |  | 
|   234 #endif |  | 
|   235  |  | 
|   236 /* |  | 
|   237 ** Functions to deserialize a 16 bit integer, 32 bit real number and |  | 
|   238 ** 64 bit integer. The deserialized value is returned. |  | 
|   239 */ |  | 
|   240 static int readInt16(u8 *p){ |  | 
|   241   return (p[0]<<8) + p[1]; |  | 
|   242 } |  | 
|   243 static void readCoord(u8 *p, RtreeCoord *pCoord){ |  | 
|   244   u32 i = ( |  | 
|   245     (((u32)p[0]) << 24) +  |  | 
|   246     (((u32)p[1]) << 16) +  |  | 
|   247     (((u32)p[2]) <<  8) +  |  | 
|   248     (((u32)p[3]) <<  0) |  | 
|   249   ); |  | 
|   250   *(u32 *)pCoord = i; |  | 
|   251 } |  | 
|   252 static i64 readInt64(u8 *p){ |  | 
|   253   return ( |  | 
|   254     (((i64)p[0]) << 56) +  |  | 
|   255     (((i64)p[1]) << 48) +  |  | 
|   256     (((i64)p[2]) << 40) +  |  | 
|   257     (((i64)p[3]) << 32) +  |  | 
|   258     (((i64)p[4]) << 24) +  |  | 
|   259     (((i64)p[5]) << 16) +  |  | 
|   260     (((i64)p[6]) <<  8) +  |  | 
|   261     (((i64)p[7]) <<  0) |  | 
|   262   ); |  | 
|   263 } |  | 
|   264  |  | 
|   265 /* |  | 
|   266 ** Functions to serialize a 16 bit integer, 32 bit real number and |  | 
|   267 ** 64 bit integer. The value returned is the number of bytes written |  | 
|   268 ** to the argument buffer (always 2, 4 and 8 respectively). |  | 
|   269 */ |  | 
|   270 static int writeInt16(u8 *p, int i){ |  | 
|   271   p[0] = (i>> 8)&0xFF; |  | 
|   272   p[1] = (i>> 0)&0xFF; |  | 
|   273   return 2; |  | 
|   274 } |  | 
|   275 static int writeCoord(u8 *p, RtreeCoord *pCoord){ |  | 
|   276   u32 i; |  | 
|   277   assert( sizeof(RtreeCoord)==4 ); |  | 
|   278   assert( sizeof(u32)==4 ); |  | 
|   279   i = *(u32 *)pCoord; |  | 
|   280   p[0] = (i>>24)&0xFF; |  | 
|   281   p[1] = (i>>16)&0xFF; |  | 
|   282   p[2] = (i>> 8)&0xFF; |  | 
|   283   p[3] = (i>> 0)&0xFF; |  | 
|   284   return 4; |  | 
|   285 } |  | 
|   286 static int writeInt64(u8 *p, i64 i){ |  | 
|   287   p[0] = (i>>56)&0xFF; |  | 
|   288   p[1] = (i>>48)&0xFF; |  | 
|   289   p[2] = (i>>40)&0xFF; |  | 
|   290   p[3] = (i>>32)&0xFF; |  | 
|   291   p[4] = (i>>24)&0xFF; |  | 
|   292   p[5] = (i>>16)&0xFF; |  | 
|   293   p[6] = (i>> 8)&0xFF; |  | 
|   294   p[7] = (i>> 0)&0xFF; |  | 
|   295   return 8; |  | 
|   296 } |  | 
|   297  |  | 
|   298 /* |  | 
|   299 ** Increment the reference count of node p. |  | 
|   300 */ |  | 
|   301 static void nodeReference(RtreeNode *p){ |  | 
|   302   if( p ){ |  | 
|   303     p->nRef++; |  | 
|   304   } |  | 
|   305 } |  | 
|   306  |  | 
|   307 /* |  | 
|   308 ** Clear the content of node p (set all bytes to 0x00). |  | 
|   309 */ |  | 
|   310 static void nodeZero(Rtree *pRtree, RtreeNode *p){ |  | 
|   311   if( p ){ |  | 
|   312     memset(&p->zData[2], 0, pRtree->iNodeSize-2); |  | 
|   313     p->isDirty = 1; |  | 
|   314   } |  | 
|   315 } |  | 
|   316  |  | 
|   317 /* |  | 
|   318 ** Given a node number iNode, return the corresponding key to use |  | 
|   319 ** in the Rtree.aHash table. |  | 
|   320 */ |  | 
|   321 static int nodeHash(i64 iNode){ |  | 
|   322   return ( |  | 
|   323     (iNode>>56) ^ (iNode>>48) ^ (iNode>>40) ^ (iNode>>32) ^  |  | 
|   324     (iNode>>24) ^ (iNode>>16) ^ (iNode>> 8) ^ (iNode>> 0) |  | 
|   325   ) % HASHSIZE; |  | 
|   326 } |  | 
|   327  |  | 
|   328 /* |  | 
|   329 ** Search the node hash table for node iNode. If found, return a pointer |  | 
|   330 ** to it. Otherwise, return 0. |  | 
|   331 */ |  | 
|   332 static RtreeNode *nodeHashLookup(Rtree *pRtree, i64 iNode){ |  | 
|   333   RtreeNode *p; |  | 
|   334   assert( iNode!=0 ); |  | 
|   335   for(p=pRtree->aHash[nodeHash(iNode)]; p && p->iNode!=iNode; p=p->pNext); |  | 
|   336   return p; |  | 
|   337 } |  | 
|   338  |  | 
|   339 /* |  | 
|   340 ** Add node pNode to the node hash table. |  | 
|   341 */ |  | 
|   342 static void nodeHashInsert(Rtree *pRtree, RtreeNode *pNode){ |  | 
|   343   if( pNode ){ |  | 
|   344     int iHash; |  | 
|   345     assert( pNode->pNext==0 ); |  | 
|   346     iHash = nodeHash(pNode->iNode); |  | 
|   347     pNode->pNext = pRtree->aHash[iHash]; |  | 
|   348     pRtree->aHash[iHash] = pNode; |  | 
|   349   } |  | 
|   350 } |  | 
|   351  |  | 
|   352 /* |  | 
|   353 ** Remove node pNode from the node hash table. |  | 
|   354 */ |  | 
|   355 static void nodeHashDelete(Rtree *pRtree, RtreeNode *pNode){ |  | 
|   356   RtreeNode **pp; |  | 
|   357   if( pNode->iNode!=0 ){ |  | 
|   358     pp = &pRtree->aHash[nodeHash(pNode->iNode)]; |  | 
|   359     for( ; (*pp)!=pNode; pp = &(*pp)->pNext){ assert(*pp); } |  | 
|   360     *pp = pNode->pNext; |  | 
|   361     pNode->pNext = 0; |  | 
|   362   } |  | 
|   363 } |  | 
|   364  |  | 
|   365 /* |  | 
|   366 ** Allocate and return new r-tree node. Initially, (RtreeNode.iNode==0), |  | 
|   367 ** indicating that node has not yet been assigned a node number. It is |  | 
|   368 ** assigned a node number when nodeWrite() is called to write the |  | 
|   369 ** node contents out to the database. |  | 
|   370 */ |  | 
|   371 static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent, int zero){ |  | 
|   372   RtreeNode *pNode; |  | 
|   373   pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode) + pRtree->iNodeSize); |  | 
|   374   if( pNode ){ |  | 
|   375     memset(pNode, 0, sizeof(RtreeNode) + (zero?pRtree->iNodeSize:0)); |  | 
|   376     pNode->zData = (u8 *)&pNode[1]; |  | 
|   377     pNode->nRef = 1; |  | 
|   378     pNode->pParent = pParent; |  | 
|   379     pNode->isDirty = 1; |  | 
|   380     nodeReference(pParent); |  | 
|   381   } |  | 
|   382   return pNode; |  | 
|   383 } |  | 
|   384  |  | 
|   385 /* |  | 
|   386 ** Obtain a reference to an r-tree node. |  | 
|   387 */ |  | 
|   388 static int |  | 
|   389 nodeAcquire( |  | 
|   390   Rtree *pRtree,             /* R-tree structure */ |  | 
|   391   i64 iNode,                 /* Node number to load */ |  | 
|   392   RtreeNode *pParent,        /* Either the parent node or NULL */ |  | 
|   393   RtreeNode **ppNode         /* OUT: Acquired node */ |  | 
|   394 ){ |  | 
|   395   int rc; |  | 
|   396   RtreeNode *pNode; |  | 
|   397  |  | 
|   398   /* Check if the requested node is already in the hash table. If so, |  | 
|   399   ** increase its reference count and return it. |  | 
|   400   */ |  | 
|   401   if( (pNode = nodeHashLookup(pRtree, iNode)) ){ |  | 
|   402     assert( !pParent || !pNode->pParent || pNode->pParent==pParent ); |  | 
|   403     if( pParent && !pNode->pParent ){ |  | 
|   404       nodeReference(pParent); |  | 
|   405       pNode->pParent = pParent; |  | 
|   406     } |  | 
|   407     pNode->nRef++; |  | 
|   408     *ppNode = pNode; |  | 
|   409     return SQLITE_OK; |  | 
|   410   } |  | 
|   411  |  | 
|   412   pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode) + pRtree->iNodeSize); |  | 
|   413   if( !pNode ){ |  | 
|   414     *ppNode = 0; |  | 
|   415     return SQLITE_NOMEM; |  | 
|   416   } |  | 
|   417   pNode->pParent = pParent; |  | 
|   418   pNode->zData = (u8 *)&pNode[1]; |  | 
|   419   pNode->nRef = 1; |  | 
|   420   pNode->iNode = iNode; |  | 
|   421   pNode->isDirty = 0; |  | 
|   422   pNode->pNext = 0; |  | 
|   423  |  | 
|   424   sqlite3_bind_int64(pRtree->pReadNode, 1, iNode); |  | 
|   425   rc = sqlite3_step(pRtree->pReadNode); |  | 
|   426   if( rc==SQLITE_ROW ){ |  | 
|   427     const u8 *zBlob = sqlite3_column_blob(pRtree->pReadNode, 0); |  | 
|   428     memcpy(pNode->zData, zBlob, pRtree->iNodeSize); |  | 
|   429     nodeReference(pParent); |  | 
|   430   }else{ |  | 
|   431     sqlite3_free(pNode); |  | 
|   432     pNode = 0; |  | 
|   433   } |  | 
|   434  |  | 
|   435   *ppNode = pNode; |  | 
|   436   rc = sqlite3_reset(pRtree->pReadNode); |  | 
|   437  |  | 
|   438   if( rc==SQLITE_OK && iNode==1 ){ |  | 
|   439     pRtree->iDepth = readInt16(pNode->zData); |  | 
|   440   } |  | 
|   441  |  | 
|   442   assert( (rc==SQLITE_OK && pNode) || (pNode==0 && rc!=SQLITE_OK) ); |  | 
|   443   nodeHashInsert(pRtree, pNode); |  | 
|   444  |  | 
|   445   return rc; |  | 
|   446 } |  | 
|   447  |  | 
|   448 /* |  | 
|   449 ** Overwrite cell iCell of node pNode with the contents of pCell. |  | 
|   450 */ |  | 
|   451 static void nodeOverwriteCell( |  | 
|   452   Rtree *pRtree,  |  | 
|   453   RtreeNode *pNode,   |  | 
|   454   RtreeCell *pCell,  |  | 
|   455   int iCell |  | 
|   456 ){ |  | 
|   457   int ii; |  | 
|   458   u8 *p = &pNode->zData[4 + pRtree->nBytesPerCell*iCell]; |  | 
|   459   p += writeInt64(p, pCell->iRowid); |  | 
|   460   for(ii=0; ii<(pRtree->nDim*2); ii++){ |  | 
|   461     p += writeCoord(p, &pCell->aCoord[ii]); |  | 
|   462   } |  | 
|   463   pNode->isDirty = 1; |  | 
|   464 } |  | 
|   465  |  | 
|   466 /* |  | 
|   467 ** Remove cell the cell with index iCell from node pNode. |  | 
|   468 */ |  | 
|   469 static void nodeDeleteCell(Rtree *pRtree, RtreeNode *pNode, int iCell){ |  | 
|   470   u8 *pDst = &pNode->zData[4 + pRtree->nBytesPerCell*iCell]; |  | 
|   471   u8 *pSrc = &pDst[pRtree->nBytesPerCell]; |  | 
|   472   int nByte = (NCELL(pNode) - iCell - 1) * pRtree->nBytesPerCell; |  | 
|   473   memmove(pDst, pSrc, nByte); |  | 
|   474   writeInt16(&pNode->zData[2], NCELL(pNode)-1); |  | 
|   475   pNode->isDirty = 1; |  | 
|   476 } |  | 
|   477  |  | 
|   478 /* |  | 
|   479 ** Insert the contents of cell pCell into node pNode. If the insert |  | 
|   480 ** is successful, return SQLITE_OK. |  | 
|   481 ** |  | 
|   482 ** If there is not enough free space in pNode, return SQLITE_FULL. |  | 
|   483 */ |  | 
|   484 static int |  | 
|   485 nodeInsertCell( |  | 
|   486   Rtree *pRtree,  |  | 
|   487   RtreeNode *pNode,  |  | 
|   488   RtreeCell *pCell  |  | 
|   489 ){ |  | 
|   490   int nCell;                    /* Current number of cells in pNode */ |  | 
|   491   int nMaxCell;                 /* Maximum number of cells for pNode */ |  | 
|   492  |  | 
|   493   nMaxCell = (pRtree->iNodeSize-4)/pRtree->nBytesPerCell; |  | 
|   494   nCell = NCELL(pNode); |  | 
|   495  |  | 
|   496   assert(nCell<=nMaxCell); |  | 
|   497  |  | 
|   498   if( nCell<nMaxCell ){ |  | 
|   499     nodeOverwriteCell(pRtree, pNode, pCell, nCell); |  | 
|   500     writeInt16(&pNode->zData[2], nCell+1); |  | 
|   501     pNode->isDirty = 1; |  | 
|   502   } |  | 
|   503  |  | 
|   504   return (nCell==nMaxCell); |  | 
|   505 } |  | 
|   506  |  | 
|   507 /* |  | 
|   508 ** If the node is dirty, write it out to the database. |  | 
|   509 */ |  | 
|   510 static int |  | 
|   511 nodeWrite(Rtree *pRtree, RtreeNode *pNode){ |  | 
|   512   int rc = SQLITE_OK; |  | 
|   513   if( pNode->isDirty ){ |  | 
|   514     sqlite3_stmt *p = pRtree->pWriteNode; |  | 
|   515     if( pNode->iNode ){ |  | 
|   516       sqlite3_bind_int64(p, 1, pNode->iNode); |  | 
|   517     }else{ |  | 
|   518       sqlite3_bind_null(p, 1); |  | 
|   519     } |  | 
|   520     sqlite3_bind_blob(p, 2, pNode->zData, pRtree->iNodeSize, SQLITE_STATIC); |  | 
|   521     sqlite3_step(p); |  | 
|   522     pNode->isDirty = 0; |  | 
|   523     rc = sqlite3_reset(p); |  | 
|   524     if( pNode->iNode==0 && rc==SQLITE_OK ){ |  | 
|   525       pNode->iNode = sqlite3_last_insert_rowid(pRtree->db); |  | 
|   526       nodeHashInsert(pRtree, pNode); |  | 
|   527     } |  | 
|   528   } |  | 
|   529   return rc; |  | 
|   530 } |  | 
|   531  |  | 
|   532 /* |  | 
|   533 ** Release a reference to a node. If the node is dirty and the reference |  | 
|   534 ** count drops to zero, the node data is written to the database. |  | 
|   535 */ |  | 
|   536 static int |  | 
|   537 nodeRelease(Rtree *pRtree, RtreeNode *pNode){ |  | 
|   538   int rc = SQLITE_OK; |  | 
|   539   if( pNode ){ |  | 
|   540     assert( pNode->nRef>0 ); |  | 
|   541     pNode->nRef--; |  | 
|   542     if( pNode->nRef==0 ){ |  | 
|   543       if( pNode->iNode==1 ){ |  | 
|   544         pRtree->iDepth = -1; |  | 
|   545       } |  | 
|   546       if( pNode->pParent ){ |  | 
|   547         rc = nodeRelease(pRtree, pNode->pParent); |  | 
|   548       } |  | 
|   549       if( rc==SQLITE_OK ){ |  | 
|   550         rc = nodeWrite(pRtree, pNode); |  | 
|   551       } |  | 
|   552       nodeHashDelete(pRtree, pNode); |  | 
|   553       sqlite3_free(pNode); |  | 
|   554     } |  | 
|   555   } |  | 
|   556   return rc; |  | 
|   557 } |  | 
|   558  |  | 
|   559 /* |  | 
|   560 ** Return the 64-bit integer value associated with cell iCell of |  | 
|   561 ** node pNode. If pNode is a leaf node, this is a rowid. If it is |  | 
|   562 ** an internal node, then the 64-bit integer is a child page number. |  | 
|   563 */ |  | 
|   564 static i64 nodeGetRowid( |  | 
|   565   Rtree *pRtree,  |  | 
|   566   RtreeNode *pNode,  |  | 
|   567   int iCell |  | 
|   568 ){ |  | 
|   569   assert( iCell<NCELL(pNode) ); |  | 
|   570   return readInt64(&pNode->zData[4 + pRtree->nBytesPerCell*iCell]); |  | 
|   571 } |  | 
|   572  |  | 
|   573 /* |  | 
|   574 ** Return coordinate iCoord from cell iCell in node pNode. |  | 
|   575 */ |  | 
|   576 static void nodeGetCoord( |  | 
|   577   Rtree *pRtree,  |  | 
|   578   RtreeNode *pNode,  |  | 
|   579   int iCell, |  | 
|   580   int iCoord, |  | 
|   581   RtreeCoord *pCoord           /* Space to write result to */ |  | 
|   582 ){ |  | 
|   583   readCoord(&pNode->zData[12 + pRtree->nBytesPerCell*iCell + 4*iCoord], pCoord); |  | 
|   584 } |  | 
|   585  |  | 
|   586 /* |  | 
|   587 ** Deserialize cell iCell of node pNode. Populate the structure pointed |  | 
|   588 ** to by pCell with the results. |  | 
|   589 */ |  | 
|   590 static void nodeGetCell( |  | 
|   591   Rtree *pRtree,  |  | 
|   592   RtreeNode *pNode,  |  | 
|   593   int iCell, |  | 
|   594   RtreeCell *pCell |  | 
|   595 ){ |  | 
|   596   int ii; |  | 
|   597   pCell->iRowid = nodeGetRowid(pRtree, pNode, iCell); |  | 
|   598   for(ii=0; ii<pRtree->nDim*2; ii++){ |  | 
|   599     nodeGetCoord(pRtree, pNode, iCell, ii, &pCell->aCoord[ii]); |  | 
|   600   } |  | 
|   601 } |  | 
|   602  |  | 
|   603  |  | 
|   604 /* Forward declaration for the function that does the work of |  | 
|   605 ** the virtual table module xCreate() and xConnect() methods. |  | 
|   606 */ |  | 
|   607 static int rtreeInit( |  | 
|   608   sqlite3 *, void *, int, const char *const*, sqlite3_vtab **, char **, int |  | 
|   609 ); |  | 
|   610  |  | 
|   611 /*  |  | 
|   612 ** Rtree virtual table module xCreate method. |  | 
|   613 */ |  | 
|   614 static int rtreeCreate( |  | 
|   615   sqlite3 *db, |  | 
|   616   void *pAux, |  | 
|   617   int argc, const char *const*argv, |  | 
|   618   sqlite3_vtab **ppVtab, |  | 
|   619   char **pzErr |  | 
|   620 ){ |  | 
|   621   return rtreeInit(db, pAux, argc, argv, ppVtab, pzErr, 1); |  | 
|   622 } |  | 
|   623  |  | 
|   624 /*  |  | 
|   625 ** Rtree virtual table module xConnect method. |  | 
|   626 */ |  | 
|   627 static int rtreeConnect( |  | 
|   628   sqlite3 *db, |  | 
|   629   void *pAux, |  | 
|   630   int argc, const char *const*argv, |  | 
|   631   sqlite3_vtab **ppVtab, |  | 
|   632   char **pzErr |  | 
|   633 ){ |  | 
|   634   return rtreeInit(db, pAux, argc, argv, ppVtab, pzErr, 0); |  | 
|   635 } |  | 
|   636  |  | 
|   637 /* |  | 
|   638 ** Increment the r-tree reference count. |  | 
|   639 */ |  | 
|   640 static void rtreeReference(Rtree *pRtree){ |  | 
|   641   pRtree->nBusy++; |  | 
|   642 } |  | 
|   643  |  | 
|   644 /* |  | 
|   645 ** Decrement the r-tree reference count. When the reference count reaches |  | 
|   646 ** zero the structure is deleted. |  | 
|   647 */ |  | 
|   648 static void rtreeRelease(Rtree *pRtree){ |  | 
|   649   pRtree->nBusy--; |  | 
|   650   if( pRtree->nBusy==0 ){ |  | 
|   651     sqlite3_finalize(pRtree->pReadNode); |  | 
|   652     sqlite3_finalize(pRtree->pWriteNode); |  | 
|   653     sqlite3_finalize(pRtree->pDeleteNode); |  | 
|   654     sqlite3_finalize(pRtree->pReadRowid); |  | 
|   655     sqlite3_finalize(pRtree->pWriteRowid); |  | 
|   656     sqlite3_finalize(pRtree->pDeleteRowid); |  | 
|   657     sqlite3_finalize(pRtree->pReadParent); |  | 
|   658     sqlite3_finalize(pRtree->pWriteParent); |  | 
|   659     sqlite3_finalize(pRtree->pDeleteParent); |  | 
|   660     sqlite3_free(pRtree); |  | 
|   661   } |  | 
|   662 } |  | 
|   663  |  | 
|   664 /*  |  | 
|   665 ** Rtree virtual table module xDisconnect method. |  | 
|   666 */ |  | 
|   667 static int rtreeDisconnect(sqlite3_vtab *pVtab){ |  | 
|   668   rtreeRelease((Rtree *)pVtab); |  | 
|   669   return SQLITE_OK; |  | 
|   670 } |  | 
|   671  |  | 
|   672 /*  |  | 
|   673 ** Rtree virtual table module xDestroy method. |  | 
|   674 */ |  | 
|   675 static int rtreeDestroy(sqlite3_vtab *pVtab){ |  | 
|   676   Rtree *pRtree = (Rtree *)pVtab; |  | 
|   677   int rc; |  | 
|   678   char *zCreate = sqlite3_mprintf( |  | 
|   679     "DROP TABLE '%q'.'%q_node';" |  | 
|   680     "DROP TABLE '%q'.'%q_rowid';" |  | 
|   681     "DROP TABLE '%q'.'%q_parent';", |  | 
|   682     pRtree->zDb, pRtree->zName,  |  | 
|   683     pRtree->zDb, pRtree->zName, |  | 
|   684     pRtree->zDb, pRtree->zName |  | 
|   685   ); |  | 
|   686   if( !zCreate ){ |  | 
|   687     rc = SQLITE_NOMEM; |  | 
|   688   }else{ |  | 
|   689     rc = sqlite3_exec(pRtree->db, zCreate, 0, 0, 0); |  | 
|   690     sqlite3_free(zCreate); |  | 
|   691   } |  | 
|   692   if( rc==SQLITE_OK ){ |  | 
|   693     rtreeRelease(pRtree); |  | 
|   694   } |  | 
|   695  |  | 
|   696   return rc; |  | 
|   697 } |  | 
|   698  |  | 
|   699 /*  |  | 
|   700 ** Rtree virtual table module xOpen method. |  | 
|   701 */ |  | 
|   702 static int rtreeOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ |  | 
|   703   int rc = SQLITE_NOMEM; |  | 
|   704   RtreeCursor *pCsr; |  | 
|   705  |  | 
|   706   pCsr = (RtreeCursor *)sqlite3_malloc(sizeof(RtreeCursor)); |  | 
|   707   if( pCsr ){ |  | 
|   708     memset(pCsr, 0, sizeof(RtreeCursor)); |  | 
|   709     pCsr->base.pVtab = pVTab; |  | 
|   710     rc = SQLITE_OK; |  | 
|   711   } |  | 
|   712   *ppCursor = (sqlite3_vtab_cursor *)pCsr; |  | 
|   713  |  | 
|   714   return rc; |  | 
|   715 } |  | 
|   716  |  | 
|   717 /*  |  | 
|   718 ** Rtree virtual table module xClose method. |  | 
|   719 */ |  | 
|   720 static int rtreeClose(sqlite3_vtab_cursor *cur){ |  | 
|   721   Rtree *pRtree = (Rtree *)(cur->pVtab); |  | 
|   722   int rc; |  | 
|   723   RtreeCursor *pCsr = (RtreeCursor *)cur; |  | 
|   724   sqlite3_free(pCsr->aConstraint); |  | 
|   725   rc = nodeRelease(pRtree, pCsr->pNode); |  | 
|   726   sqlite3_free(pCsr); |  | 
|   727   return rc; |  | 
|   728 } |  | 
|   729  |  | 
|   730 /* |  | 
|   731 ** Rtree virtual table module xEof method. |  | 
|   732 ** |  | 
|   733 ** Return non-zero if the cursor does not currently point to a valid  |  | 
|   734 ** record (i.e if the scan has finished), or zero otherwise. |  | 
|   735 */ |  | 
|   736 static int rtreeEof(sqlite3_vtab_cursor *cur){ |  | 
|   737   RtreeCursor *pCsr = (RtreeCursor *)cur; |  | 
|   738   return (pCsr->pNode==0); |  | 
|   739 } |  | 
|   740  |  | 
|   741 /*  |  | 
|   742 ** Cursor pCursor currently points to a cell in a non-leaf page. |  | 
|   743 ** Return true if the sub-tree headed by the cell is filtered |  | 
|   744 ** (excluded) by the constraints in the pCursor->aConstraint[]  |  | 
|   745 ** array, or false otherwise. |  | 
|   746 */ |  | 
|   747 static int testRtreeCell(Rtree *pRtree, RtreeCursor *pCursor){ |  | 
|   748   RtreeCell cell; |  | 
|   749   int ii; |  | 
|   750   int bRes = 0; |  | 
|   751  |  | 
|   752   nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell); |  | 
|   753   for(ii=0; bRes==0 && ii<pCursor->nConstraint; ii++){ |  | 
|   754     RtreeConstraint *p = &pCursor->aConstraint[ii]; |  | 
|   755     double cell_min = DCOORD(cell.aCoord[(p->iCoord>>1)*2]); |  | 
|   756     double cell_max = DCOORD(cell.aCoord[(p->iCoord>>1)*2+1]); |  | 
|   757  |  | 
|   758     assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE  |  | 
|   759         || p->op==RTREE_GT || p->op==RTREE_EQ |  | 
|   760     ); |  | 
|   761  |  | 
|   762     switch( p->op ){ |  | 
|   763       case RTREE_LE: case RTREE_LT: bRes = p->rValue<cell_min; break; |  | 
|   764       case RTREE_GE: case RTREE_GT: bRes = p->rValue>cell_max; break; |  | 
|   765       case RTREE_EQ:  |  | 
|   766         bRes = (p->rValue>cell_max || p->rValue<cell_min); |  | 
|   767         break; |  | 
|   768     } |  | 
|   769   } |  | 
|   770  |  | 
|   771   return bRes; |  | 
|   772 } |  | 
|   773  |  | 
|   774 /*  |  | 
|   775 ** Return true if the cell that cursor pCursor currently points to |  | 
|   776 ** would be filtered (excluded) by the constraints in the  |  | 
|   777 ** pCursor->aConstraint[] array, or false otherwise. |  | 
|   778 ** |  | 
|   779 ** This function assumes that the cell is part of a leaf node. |  | 
|   780 */ |  | 
|   781 static int testRtreeEntry(Rtree *pRtree, RtreeCursor *pCursor){ |  | 
|   782   RtreeCell cell; |  | 
|   783   int ii; |  | 
|   784  |  | 
|   785   nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell); |  | 
|   786   for(ii=0; ii<pCursor->nConstraint; ii++){ |  | 
|   787     RtreeConstraint *p = &pCursor->aConstraint[ii]; |  | 
|   788     double coord = DCOORD(cell.aCoord[p->iCoord]); |  | 
|   789     int res; |  | 
|   790     assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE  |  | 
|   791         || p->op==RTREE_GT || p->op==RTREE_EQ |  | 
|   792     ); |  | 
|   793     switch( p->op ){ |  | 
|   794       case RTREE_LE: res = (coord<=p->rValue); break; |  | 
|   795       case RTREE_LT: res = (coord<p->rValue);  break; |  | 
|   796       case RTREE_GE: res = (coord>=p->rValue); break; |  | 
|   797       case RTREE_GT: res = (coord>p->rValue);  break; |  | 
|   798       case RTREE_EQ: res = (coord==p->rValue); break; |  | 
|   799     } |  | 
|   800  |  | 
|   801     if( !res ) return 1; |  | 
|   802   } |  | 
|   803  |  | 
|   804   return 0; |  | 
|   805 } |  | 
|   806  |  | 
|   807 /* |  | 
|   808 ** Cursor pCursor currently points at a node that heads a sub-tree of |  | 
|   809 ** height iHeight (if iHeight==0, then the node is a leaf). Descend |  | 
|   810 ** to point to the left-most cell of the sub-tree that matches the  |  | 
|   811 ** configured constraints. |  | 
|   812 */ |  | 
|   813 static int descendToCell( |  | 
|   814   Rtree *pRtree,  |  | 
|   815   RtreeCursor *pCursor,  |  | 
|   816   int iHeight, |  | 
|   817   int *pEof                 /* OUT: Set to true if cannot descend */ |  | 
|   818 ){ |  | 
|   819   int isEof; |  | 
|   820   int rc; |  | 
|   821   int ii; |  | 
|   822   RtreeNode *pChild; |  | 
|   823   sqlite3_int64 iRowid; |  | 
|   824  |  | 
|   825   RtreeNode *pSavedNode = pCursor->pNode; |  | 
|   826   int iSavedCell = pCursor->iCell; |  | 
|   827  |  | 
|   828   assert( iHeight>=0 ); |  | 
|   829  |  | 
|   830   if( iHeight==0 ){ |  | 
|   831     isEof = testRtreeEntry(pRtree, pCursor); |  | 
|   832   }else{ |  | 
|   833     isEof = testRtreeCell(pRtree, pCursor); |  | 
|   834   } |  | 
|   835   if( isEof || iHeight==0 ){ |  | 
|   836     *pEof = isEof; |  | 
|   837     return SQLITE_OK; |  | 
|   838   } |  | 
|   839  |  | 
|   840   iRowid = nodeGetRowid(pRtree, pCursor->pNode, pCursor->iCell); |  | 
|   841   rc = nodeAcquire(pRtree, iRowid, pCursor->pNode, &pChild); |  | 
|   842   if( rc!=SQLITE_OK ){ |  | 
|   843     return rc; |  | 
|   844   } |  | 
|   845  |  | 
|   846   nodeRelease(pRtree, pCursor->pNode); |  | 
|   847   pCursor->pNode = pChild; |  | 
|   848   isEof = 1; |  | 
|   849   for(ii=0; isEof && ii<NCELL(pChild); ii++){ |  | 
|   850     pCursor->iCell = ii; |  | 
|   851     rc = descendToCell(pRtree, pCursor, iHeight-1, &isEof); |  | 
|   852     if( rc!=SQLITE_OK ){ |  | 
|   853       return rc; |  | 
|   854     } |  | 
|   855   } |  | 
|   856  |  | 
|   857   if( isEof ){ |  | 
|   858     assert( pCursor->pNode==pChild ); |  | 
|   859     nodeReference(pSavedNode); |  | 
|   860     nodeRelease(pRtree, pChild); |  | 
|   861     pCursor->pNode = pSavedNode; |  | 
|   862     pCursor->iCell = iSavedCell; |  | 
|   863   } |  | 
|   864  |  | 
|   865   *pEof = isEof; |  | 
|   866   return SQLITE_OK; |  | 
|   867 } |  | 
|   868  |  | 
|   869 /* |  | 
|   870 ** One of the cells in node pNode is guaranteed to have a 64-bit  |  | 
|   871 ** integer value equal to iRowid. Return the index of this cell. |  | 
|   872 */ |  | 
|   873 static int nodeRowidIndex(Rtree *pRtree, RtreeNode *pNode, i64 iRowid){ |  | 
|   874   int ii; |  | 
|   875   for(ii=0; nodeGetRowid(pRtree, pNode, ii)!=iRowid; ii++){ |  | 
|   876     assert( ii<(NCELL(pNode)-1) ); |  | 
|   877   } |  | 
|   878   return ii; |  | 
|   879 } |  | 
|   880  |  | 
|   881 /* |  | 
|   882 ** Return the index of the cell containing a pointer to node pNode |  | 
|   883 ** in its parent. If pNode is the root node, return -1. |  | 
|   884 */ |  | 
|   885 static int nodeParentIndex(Rtree *pRtree, RtreeNode *pNode){ |  | 
|   886   RtreeNode *pParent = pNode->pParent; |  | 
|   887   if( pParent ){ |  | 
|   888     return nodeRowidIndex(pRtree, pParent, pNode->iNode); |  | 
|   889   } |  | 
|   890   return -1; |  | 
|   891 } |  | 
|   892  |  | 
|   893 /*  |  | 
|   894 ** Rtree virtual table module xNext method. |  | 
|   895 */ |  | 
|   896 static int rtreeNext(sqlite3_vtab_cursor *pVtabCursor){ |  | 
|   897   Rtree *pRtree = (Rtree *)(pVtabCursor->pVtab); |  | 
|   898   RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; |  | 
|   899   int rc = SQLITE_OK; |  | 
|   900  |  | 
|   901   if( pCsr->iStrategy==1 ){ |  | 
|   902     /* This "scan" is a direct lookup by rowid. There is no next entry. */ |  | 
|   903     nodeRelease(pRtree, pCsr->pNode); |  | 
|   904     pCsr->pNode = 0; |  | 
|   905   } |  | 
|   906  |  | 
|   907   else if( pCsr->pNode ){ |  | 
|   908     /* Move to the next entry that matches the configured constraints. */ |  | 
|   909     int iHeight = 0; |  | 
|   910     while( pCsr->pNode ){ |  | 
|   911       RtreeNode *pNode = pCsr->pNode; |  | 
|   912       int nCell = NCELL(pNode); |  | 
|   913       for(pCsr->iCell++; pCsr->iCell<nCell; pCsr->iCell++){ |  | 
|   914         int isEof; |  | 
|   915         rc = descendToCell(pRtree, pCsr, iHeight, &isEof); |  | 
|   916         if( rc!=SQLITE_OK || !isEof ){ |  | 
|   917           return rc; |  | 
|   918         } |  | 
|   919       } |  | 
|   920       pCsr->pNode = pNode->pParent; |  | 
|   921       pCsr->iCell = nodeParentIndex(pRtree, pNode); |  | 
|   922       nodeReference(pCsr->pNode); |  | 
|   923       nodeRelease(pRtree, pNode); |  | 
|   924       iHeight++; |  | 
|   925     } |  | 
|   926   } |  | 
|   927  |  | 
|   928   return rc; |  | 
|   929 } |  | 
|   930  |  | 
|   931 /*  |  | 
|   932 ** Rtree virtual table module xRowid method. |  | 
|   933 */ |  | 
|   934 static int rtreeRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *pRowid){ |  | 
|   935   Rtree *pRtree = (Rtree *)pVtabCursor->pVtab; |  | 
|   936   RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; |  | 
|   937  |  | 
|   938   assert(pCsr->pNode); |  | 
|   939   *pRowid = nodeGetRowid(pRtree, pCsr->pNode, pCsr->iCell); |  | 
|   940  |  | 
|   941   return SQLITE_OK; |  | 
|   942 } |  | 
|   943  |  | 
|   944 /*  |  | 
|   945 ** Rtree virtual table module xColumn method. |  | 
|   946 */ |  | 
|   947 static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ |  | 
|   948   Rtree *pRtree = (Rtree *)cur->pVtab; |  | 
|   949   RtreeCursor *pCsr = (RtreeCursor *)cur; |  | 
|   950  |  | 
|   951   if( i==0 ){ |  | 
|   952     i64 iRowid = nodeGetRowid(pRtree, pCsr->pNode, pCsr->iCell); |  | 
|   953     sqlite3_result_int64(ctx, iRowid); |  | 
|   954   }else{ |  | 
|   955     RtreeCoord c; |  | 
|   956     nodeGetCoord(pRtree, pCsr->pNode, pCsr->iCell, i-1, &c); |  | 
|   957     if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ |  | 
|   958       sqlite3_result_double(ctx, c.f); |  | 
|   959     }else{ |  | 
|   960       assert( pRtree->eCoordType==RTREE_COORD_INT32 ); |  | 
|   961       sqlite3_result_int(ctx, c.i); |  | 
|   962     } |  | 
|   963   } |  | 
|   964  |  | 
|   965   return SQLITE_OK; |  | 
|   966 } |  | 
|   967  |  | 
|   968 /*  |  | 
|   969 ** Use nodeAcquire() to obtain the leaf node containing the record with  |  | 
|   970 ** rowid iRowid. If successful, set *ppLeaf to point to the node and |  | 
|   971 ** return SQLITE_OK. If there is no such record in the table, set |  | 
|   972 ** *ppLeaf to 0 and return SQLITE_OK. If an error occurs, set *ppLeaf |  | 
|   973 ** to zero and return an SQLite error code. |  | 
|   974 */ |  | 
|   975 static int findLeafNode(Rtree *pRtree, i64 iRowid, RtreeNode **ppLeaf){ |  | 
|   976   int rc; |  | 
|   977   *ppLeaf = 0; |  | 
|   978   sqlite3_bind_int64(pRtree->pReadRowid, 1, iRowid); |  | 
|   979   if( sqlite3_step(pRtree->pReadRowid)==SQLITE_ROW ){ |  | 
|   980     i64 iNode = sqlite3_column_int64(pRtree->pReadRowid, 0); |  | 
|   981     rc = nodeAcquire(pRtree, iNode, 0, ppLeaf); |  | 
|   982     sqlite3_reset(pRtree->pReadRowid); |  | 
|   983   }else{ |  | 
|   984     rc = sqlite3_reset(pRtree->pReadRowid); |  | 
|   985   } |  | 
|   986   return rc; |  | 
|   987 } |  | 
|   988  |  | 
|   989  |  | 
|   990 /*  |  | 
|   991 ** Rtree virtual table module xFilter method. |  | 
|   992 */ |  | 
|   993 static int rtreeFilter( |  | 
|   994   sqlite3_vtab_cursor *pVtabCursor,  |  | 
|   995   int idxNum, const char *idxStr, |  | 
|   996   int argc, sqlite3_value **argv |  | 
|   997 ){ |  | 
|   998   Rtree *pRtree = (Rtree *)pVtabCursor->pVtab; |  | 
|   999   RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; |  | 
|  1000  |  | 
|  1001   RtreeNode *pRoot = 0; |  | 
|  1002   int ii; |  | 
|  1003   int rc = SQLITE_OK; |  | 
|  1004  |  | 
|  1005   rtreeReference(pRtree); |  | 
|  1006  |  | 
|  1007   sqlite3_free(pCsr->aConstraint); |  | 
|  1008   pCsr->aConstraint = 0; |  | 
|  1009   pCsr->iStrategy = idxNum; |  | 
|  1010  |  | 
|  1011   if( idxNum==1 ){ |  | 
|  1012     /* Special case - lookup by rowid. */ |  | 
|  1013     RtreeNode *pLeaf;        /* Leaf on which the required cell resides */ |  | 
|  1014     i64 iRowid = sqlite3_value_int64(argv[0]); |  | 
|  1015     rc = findLeafNode(pRtree, iRowid, &pLeaf); |  | 
|  1016     pCsr->pNode = pLeaf;  |  | 
|  1017     if( pLeaf && rc==SQLITE_OK ){ |  | 
|  1018       pCsr->iCell = nodeRowidIndex(pRtree, pLeaf, iRowid); |  | 
|  1019     } |  | 
|  1020   }else{ |  | 
|  1021     /* Normal case - r-tree scan. Set up the RtreeCursor.aConstraint array  |  | 
|  1022     ** with the configured constraints.  |  | 
|  1023     */ |  | 
|  1024     if( argc>0 ){ |  | 
|  1025       pCsr->aConstraint = sqlite3_malloc(sizeof(RtreeConstraint)*argc); |  | 
|  1026       pCsr->nConstraint = argc; |  | 
|  1027       if( !pCsr->aConstraint ){ |  | 
|  1028         rc = SQLITE_NOMEM; |  | 
|  1029       }else{ |  | 
|  1030         assert( (idxStr==0 && argc==0) || strlen(idxStr)==argc*2 ); |  | 
|  1031         for(ii=0; ii<argc; ii++){ |  | 
|  1032           RtreeConstraint *p = &pCsr->aConstraint[ii]; |  | 
|  1033           p->op = idxStr[ii*2]; |  | 
|  1034           p->iCoord = idxStr[ii*2+1]-'a'; |  | 
|  1035           p->rValue = sqlite3_value_double(argv[ii]); |  | 
|  1036         } |  | 
|  1037       } |  | 
|  1038     } |  | 
|  1039    |  | 
|  1040     if( rc==SQLITE_OK ){ |  | 
|  1041       pCsr->pNode = 0; |  | 
|  1042       rc = nodeAcquire(pRtree, 1, 0, &pRoot); |  | 
|  1043     } |  | 
|  1044     if( rc==SQLITE_OK ){ |  | 
|  1045       int isEof = 1; |  | 
|  1046       int nCell = NCELL(pRoot); |  | 
|  1047       pCsr->pNode = pRoot; |  | 
|  1048       for(pCsr->iCell=0; rc==SQLITE_OK && pCsr->iCell<nCell; pCsr->iCell++){ |  | 
|  1049         assert( pCsr->pNode==pRoot ); |  | 
|  1050         rc = descendToCell(pRtree, pCsr, pRtree->iDepth, &isEof); |  | 
|  1051         if( !isEof ){ |  | 
|  1052           break; |  | 
|  1053         } |  | 
|  1054       } |  | 
|  1055       if( rc==SQLITE_OK && isEof ){ |  | 
|  1056         assert( pCsr->pNode==pRoot ); |  | 
|  1057         nodeRelease(pRtree, pRoot); |  | 
|  1058         pCsr->pNode = 0; |  | 
|  1059       } |  | 
|  1060       assert( rc!=SQLITE_OK || !pCsr->pNode || pCsr->iCell<NCELL(pCsr->pNode) ); |  | 
|  1061     } |  | 
|  1062   } |  | 
|  1063  |  | 
|  1064   rtreeRelease(pRtree); |  | 
|  1065   return rc; |  | 
|  1066 } |  | 
|  1067  |  | 
|  1068 /* |  | 
|  1069 ** Rtree virtual table module xBestIndex method. There are three |  | 
|  1070 ** table scan strategies to choose from (in order from most to  |  | 
|  1071 ** least desirable): |  | 
|  1072 ** |  | 
|  1073 **   idxNum     idxStr        Strategy |  | 
|  1074 **   ------------------------------------------------ |  | 
|  1075 **     1        Unused        Direct lookup by rowid. |  | 
|  1076 **     2        See below     R-tree query. |  | 
|  1077 **     3        Unused        Full table scan. |  | 
|  1078 **   ------------------------------------------------ |  | 
|  1079 ** |  | 
|  1080 ** If strategy 1 or 3 is used, then idxStr is not meaningful. If strategy |  | 
|  1081 ** 2 is used, idxStr is formatted to contain 2 bytes for each  |  | 
|  1082 ** constraint used. The first two bytes of idxStr correspond to  |  | 
|  1083 ** the constraint in sqlite3_index_info.aConstraintUsage[] with |  | 
|  1084 ** (argvIndex==1) etc. |  | 
|  1085 ** |  | 
|  1086 ** The first of each pair of bytes in idxStr identifies the constraint |  | 
|  1087 ** operator as follows: |  | 
|  1088 ** |  | 
|  1089 **   Operator    Byte Value |  | 
|  1090 **   ---------------------- |  | 
|  1091 **      =        0x41 ('A') |  | 
|  1092 **     <=        0x42 ('B') |  | 
|  1093 **      <        0x43 ('C') |  | 
|  1094 **     >=        0x44 ('D') |  | 
|  1095 **      >        0x45 ('E') |  | 
|  1096 **   ---------------------- |  | 
|  1097 ** |  | 
|  1098 ** The second of each pair of bytes identifies the coordinate column |  | 
|  1099 ** to which the constraint applies. The leftmost coordinate column |  | 
|  1100 ** is 'a', the second from the left 'b' etc. |  | 
|  1101 */ |  | 
|  1102 static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ |  | 
|  1103   int rc = SQLITE_OK; |  | 
|  1104   int ii, cCol; |  | 
|  1105  |  | 
|  1106   int iIdx = 0; |  | 
|  1107   char zIdxStr[RTREE_MAX_DIMENSIONS*8+1]; |  | 
|  1108   memset(zIdxStr, 0, sizeof(zIdxStr)); |  | 
|  1109  |  | 
|  1110   assert( pIdxInfo->idxStr==0 ); |  | 
|  1111   for(ii=0; ii<pIdxInfo->nConstraint; ii++){ |  | 
|  1112     struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii]; |  | 
|  1113  |  | 
|  1114     if( p->usable && p->iColumn==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){ |  | 
|  1115       /* We have an equality constraint on the rowid. Use strategy 1. */ |  | 
|  1116       int jj; |  | 
|  1117       for(jj=0; jj<ii; jj++){ |  | 
|  1118         pIdxInfo->aConstraintUsage[jj].argvIndex = 0; |  | 
|  1119         pIdxInfo->aConstraintUsage[jj].omit = 0; |  | 
|  1120       } |  | 
|  1121       pIdxInfo->idxNum = 1; |  | 
|  1122       pIdxInfo->aConstraintUsage[ii].argvIndex = 1; |  | 
|  1123       pIdxInfo->aConstraintUsage[jj].omit = 1; |  | 
|  1124  |  | 
|  1125       /* This strategy involves a two rowid lookups on an B-Tree structures |  | 
|  1126       ** and then a linear search of an R-Tree node. This should be  |  | 
|  1127       ** considered almost as quick as a direct rowid lookup (for which  |  | 
|  1128       ** sqlite uses an internal cost of 0.0). |  | 
|  1129       */  |  | 
|  1130       pIdxInfo->estimatedCost = 10.0; |  | 
|  1131       return SQLITE_OK; |  | 
|  1132     } |  | 
|  1133  |  | 
|  1134     if( p->usable && p->iColumn>0 ){ |  | 
|  1135       u8 op = 0; |  | 
|  1136       switch( p->op ){ |  | 
|  1137         case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; break; |  | 
|  1138         case SQLITE_INDEX_CONSTRAINT_GT: op = RTREE_GT; break; |  | 
|  1139         case SQLITE_INDEX_CONSTRAINT_LE: op = RTREE_LE; break; |  | 
|  1140         case SQLITE_INDEX_CONSTRAINT_LT: op = RTREE_LT; break; |  | 
|  1141         case SQLITE_INDEX_CONSTRAINT_GE: op = RTREE_GE; break; |  | 
|  1142       } |  | 
|  1143       if( op ){ |  | 
|  1144         /* Make sure this particular constraint has not been used before. |  | 
|  1145         ** If it has been used before, ignore it. |  | 
|  1146         ** |  | 
|  1147         ** A <= or < can be used if there is a prior >= or >. |  | 
|  1148         ** A >= or > can be used if there is a prior < or <=. |  | 
|  1149         ** A <= or < is disqualified if there is a prior <=, <, or ==. |  | 
|  1150         ** A >= or > is disqualified if there is a prior >=, >, or ==. |  | 
|  1151         ** A == is disqualifed if there is any prior constraint. |  | 
|  1152         */ |  | 
|  1153         int j, opmsk; |  | 
|  1154         static const unsigned char compatible[] = { 0, 0, 1, 1, 2, 2 }; |  | 
|  1155         assert( compatible[RTREE_EQ & 7]==0 ); |  | 
|  1156         assert( compatible[RTREE_LT & 7]==1 ); |  | 
|  1157         assert( compatible[RTREE_LE & 7]==1 ); |  | 
|  1158         assert( compatible[RTREE_GT & 7]==2 ); |  | 
|  1159         assert( compatible[RTREE_GE & 7]==2 ); |  | 
|  1160         cCol = p->iColumn - 1 + 'a'; |  | 
|  1161         opmsk = compatible[op & 7]; |  | 
|  1162         for(j=0; j<iIdx; j+=2){ |  | 
|  1163           if( zIdxStr[j+1]==cCol && (compatible[zIdxStr[j] & 7] & opmsk)!=0 ){ |  | 
|  1164             op = 0; |  | 
|  1165             break; |  | 
|  1166           } |  | 
|  1167         } |  | 
|  1168       } |  | 
|  1169       if( op ){ |  | 
|  1170         assert( iIdx<sizeof(zIdxStr)-1 ); |  | 
|  1171         zIdxStr[iIdx++] = op; |  | 
|  1172         zIdxStr[iIdx++] = cCol; |  | 
|  1173         pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2); |  | 
|  1174         pIdxInfo->aConstraintUsage[ii].omit = 1; |  | 
|  1175       } |  | 
|  1176     } |  | 
|  1177   } |  | 
|  1178  |  | 
|  1179   pIdxInfo->idxNum = 2; |  | 
|  1180   pIdxInfo->needToFreeIdxStr = 1; |  | 
|  1181   if( iIdx>0 && 0==(pIdxInfo->idxStr = sqlite3_mprintf("%s", zIdxStr)) ){ |  | 
|  1182     return SQLITE_NOMEM; |  | 
|  1183   } |  | 
|  1184   assert( iIdx>=0 ); |  | 
|  1185   pIdxInfo->estimatedCost = (2000000.0 / (double)(iIdx + 1)); |  | 
|  1186   return rc; |  | 
|  1187 } |  | 
|  1188  |  | 
|  1189 /* |  | 
|  1190 ** Return the N-dimensional volumn of the cell stored in *p. |  | 
|  1191 */ |  | 
|  1192 static float cellArea(Rtree *pRtree, RtreeCell *p){ |  | 
|  1193   float area = 1.0; |  | 
|  1194   int ii; |  | 
|  1195   for(ii=0; ii<(pRtree->nDim*2); ii+=2){ |  | 
|  1196     area = area * (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii])); |  | 
|  1197   } |  | 
|  1198   return area; |  | 
|  1199 } |  | 
|  1200  |  | 
|  1201 /* |  | 
|  1202 ** Return the margin length of cell p. The margin length is the sum |  | 
|  1203 ** of the objects size in each dimension. |  | 
|  1204 */ |  | 
|  1205 static float cellMargin(Rtree *pRtree, RtreeCell *p){ |  | 
|  1206   float margin = 0.0; |  | 
|  1207   int ii; |  | 
|  1208   for(ii=0; ii<(pRtree->nDim*2); ii+=2){ |  | 
|  1209     margin += (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii])); |  | 
|  1210   } |  | 
|  1211   return margin; |  | 
|  1212 } |  | 
|  1213  |  | 
|  1214 /* |  | 
|  1215 ** Store the union of cells p1 and p2 in p1. |  | 
|  1216 */ |  | 
|  1217 static void cellUnion(Rtree *pRtree, RtreeCell *p1, RtreeCell *p2){ |  | 
|  1218   int ii; |  | 
|  1219   if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ |  | 
|  1220     for(ii=0; ii<(pRtree->nDim*2); ii+=2){ |  | 
|  1221       p1->aCoord[ii].f = MIN(p1->aCoord[ii].f, p2->aCoord[ii].f); |  | 
|  1222       p1->aCoord[ii+1].f = MAX(p1->aCoord[ii+1].f, p2->aCoord[ii+1].f); |  | 
|  1223     } |  | 
|  1224   }else{ |  | 
|  1225     for(ii=0; ii<(pRtree->nDim*2); ii+=2){ |  | 
|  1226       p1->aCoord[ii].i = MIN(p1->aCoord[ii].i, p2->aCoord[ii].i); |  | 
|  1227       p1->aCoord[ii+1].i = MAX(p1->aCoord[ii+1].i, p2->aCoord[ii+1].i); |  | 
|  1228     } |  | 
|  1229   } |  | 
|  1230 } |  | 
|  1231  |  | 
|  1232 /* |  | 
|  1233 ** Return true if the area covered by p2 is a subset of the area covered |  | 
|  1234 ** by p1. False otherwise. |  | 
|  1235 */ |  | 
|  1236 static int cellContains(Rtree *pRtree, RtreeCell *p1, RtreeCell *p2){ |  | 
|  1237   int ii; |  | 
|  1238   int isInt = (pRtree->eCoordType==RTREE_COORD_INT32); |  | 
|  1239   for(ii=0; ii<(pRtree->nDim*2); ii+=2){ |  | 
|  1240     RtreeCoord *a1 = &p1->aCoord[ii]; |  | 
|  1241     RtreeCoord *a2 = &p2->aCoord[ii]; |  | 
|  1242     if( (!isInt && (a2[0].f<a1[0].f || a2[1].f>a1[1].f))  |  | 
|  1243      || ( isInt && (a2[0].i<a1[0].i || a2[1].i>a1[1].i))  |  | 
|  1244     ){ |  | 
|  1245       return 0; |  | 
|  1246     } |  | 
|  1247   } |  | 
|  1248   return 1; |  | 
|  1249 } |  | 
|  1250  |  | 
|  1251 /* |  | 
|  1252 ** Return the amount cell p would grow by if it were unioned with pCell. |  | 
|  1253 */ |  | 
|  1254 static float cellGrowth(Rtree *pRtree, RtreeCell *p, RtreeCell *pCell){ |  | 
|  1255   float area; |  | 
|  1256   RtreeCell cell; |  | 
|  1257   memcpy(&cell, p, sizeof(RtreeCell)); |  | 
|  1258   area = cellArea(pRtree, &cell); |  | 
|  1259   cellUnion(pRtree, &cell, pCell); |  | 
|  1260   return (cellArea(pRtree, &cell)-area); |  | 
|  1261 } |  | 
|  1262  |  | 
|  1263 #if VARIANT_RSTARTREE_CHOOSESUBTREE || VARIANT_RSTARTREE_SPLIT |  | 
|  1264 static float cellOverlap( |  | 
|  1265   Rtree *pRtree,  |  | 
|  1266   RtreeCell *p,  |  | 
|  1267   RtreeCell *aCell,  |  | 
|  1268   int nCell,  |  | 
|  1269   int iExclude |  | 
|  1270 ){ |  | 
|  1271   int ii; |  | 
|  1272   float overlap = 0.0; |  | 
|  1273   for(ii=0; ii<nCell; ii++){ |  | 
|  1274     if( ii!=iExclude ){ |  | 
|  1275       int jj; |  | 
|  1276       float o = 1.0; |  | 
|  1277       for(jj=0; jj<(pRtree->nDim*2); jj+=2){ |  | 
|  1278         double x1; |  | 
|  1279         double x2; |  | 
|  1280  |  | 
|  1281         x1 = MAX(DCOORD(p->aCoord[jj]), DCOORD(aCell[ii].aCoord[jj])); |  | 
|  1282         x2 = MIN(DCOORD(p->aCoord[jj+1]), DCOORD(aCell[ii].aCoord[jj+1])); |  | 
|  1283  |  | 
|  1284         if( x2<x1 ){ |  | 
|  1285           o = 0.0; |  | 
|  1286           break; |  | 
|  1287         }else{ |  | 
|  1288           o = o * (x2-x1); |  | 
|  1289         } |  | 
|  1290       } |  | 
|  1291       overlap += o; |  | 
|  1292     } |  | 
|  1293   } |  | 
|  1294   return overlap; |  | 
|  1295 } |  | 
|  1296 #endif |  | 
|  1297  |  | 
|  1298 #if VARIANT_RSTARTREE_CHOOSESUBTREE |  | 
|  1299 static float cellOverlapEnlargement( |  | 
|  1300   Rtree *pRtree,  |  | 
|  1301   RtreeCell *p,  |  | 
|  1302   RtreeCell *pInsert,  |  | 
|  1303   RtreeCell *aCell,  |  | 
|  1304   int nCell,  |  | 
|  1305   int iExclude |  | 
|  1306 ){ |  | 
|  1307   float before; |  | 
|  1308   float after; |  | 
|  1309   before = cellOverlap(pRtree, p, aCell, nCell, iExclude); |  | 
|  1310   cellUnion(pRtree, p, pInsert); |  | 
|  1311   after = cellOverlap(pRtree, p, aCell, nCell, iExclude); |  | 
|  1312   return after-before; |  | 
|  1313 } |  | 
|  1314 #endif |  | 
|  1315  |  | 
|  1316  |  | 
|  1317 /* |  | 
|  1318 ** This function implements the ChooseLeaf algorithm from Gutman[84]. |  | 
|  1319 ** ChooseSubTree in r*tree terminology. |  | 
|  1320 */ |  | 
|  1321 static int ChooseLeaf( |  | 
|  1322   Rtree *pRtree,               /* Rtree table */ |  | 
|  1323   RtreeCell *pCell,            /* Cell to insert into rtree */ |  | 
|  1324   int iHeight,                 /* Height of sub-tree rooted at pCell */ |  | 
|  1325   RtreeNode **ppLeaf           /* OUT: Selected leaf page */ |  | 
|  1326 ){ |  | 
|  1327   int rc; |  | 
|  1328   int ii; |  | 
|  1329   RtreeNode *pNode; |  | 
|  1330   rc = nodeAcquire(pRtree, 1, 0, &pNode); |  | 
|  1331  |  | 
|  1332   for(ii=0; rc==SQLITE_OK && ii<(pRtree->iDepth-iHeight); ii++){ |  | 
|  1333     int iCell; |  | 
|  1334     sqlite3_int64 iBest; |  | 
|  1335  |  | 
|  1336     float fMinGrowth; |  | 
|  1337     float fMinArea; |  | 
|  1338     float fMinOverlap; |  | 
|  1339  |  | 
|  1340     int nCell = NCELL(pNode); |  | 
|  1341     RtreeCell cell; |  | 
|  1342     RtreeNode *pChild; |  | 
|  1343  |  | 
|  1344     RtreeCell *aCell = 0; |  | 
|  1345  |  | 
|  1346 #if VARIANT_RSTARTREE_CHOOSESUBTREE |  | 
|  1347     if( ii==(pRtree->iDepth-1) ){ |  | 
|  1348       int jj; |  | 
|  1349       aCell = sqlite3_malloc(sizeof(RtreeCell)*nCell); |  | 
|  1350       if( !aCell ){ |  | 
|  1351         rc = SQLITE_NOMEM; |  | 
|  1352         nodeRelease(pRtree, pNode); |  | 
|  1353         pNode = 0; |  | 
|  1354         continue; |  | 
|  1355       } |  | 
|  1356       for(jj=0; jj<nCell; jj++){ |  | 
|  1357         nodeGetCell(pRtree, pNode, jj, &aCell[jj]); |  | 
|  1358       } |  | 
|  1359     } |  | 
|  1360 #endif |  | 
|  1361  |  | 
|  1362     /* Select the child node which will be enlarged the least if pCell |  | 
|  1363     ** is inserted into it. Resolve ties by choosing the entry with |  | 
|  1364     ** the smallest area. |  | 
|  1365     */ |  | 
|  1366     for(iCell=0; iCell<nCell; iCell++){ |  | 
|  1367       float growth; |  | 
|  1368       float area; |  | 
|  1369       float overlap = 0.0; |  | 
|  1370       nodeGetCell(pRtree, pNode, iCell, &cell); |  | 
|  1371       growth = cellGrowth(pRtree, &cell, pCell); |  | 
|  1372       area = cellArea(pRtree, &cell); |  | 
|  1373 #if VARIANT_RSTARTREE_CHOOSESUBTREE |  | 
|  1374       if( ii==(pRtree->iDepth-1) ){ |  | 
|  1375         overlap = cellOverlapEnlargement(pRtree,&cell,pCell,aCell,nCell,iCell); |  | 
|  1376       } |  | 
|  1377 #endif |  | 
|  1378       if( (iCell==0)  |  | 
|  1379        || (overlap<fMinOverlap)  |  | 
|  1380        || (overlap==fMinOverlap && growth<fMinGrowth) |  | 
|  1381        || (overlap==fMinOverlap && growth==fMinGrowth && area<fMinArea) |  | 
|  1382       ){ |  | 
|  1383         fMinOverlap = overlap; |  | 
|  1384         fMinGrowth = growth; |  | 
|  1385         fMinArea = area; |  | 
|  1386         iBest = cell.iRowid; |  | 
|  1387       } |  | 
|  1388     } |  | 
|  1389  |  | 
|  1390     sqlite3_free(aCell); |  | 
|  1391     rc = nodeAcquire(pRtree, iBest, pNode, &pChild); |  | 
|  1392     nodeRelease(pRtree, pNode); |  | 
|  1393     pNode = pChild; |  | 
|  1394   } |  | 
|  1395  |  | 
|  1396   *ppLeaf = pNode; |  | 
|  1397   return rc; |  | 
|  1398 } |  | 
|  1399  |  | 
|  1400 /* |  | 
|  1401 ** A cell with the same content as pCell has just been inserted into |  | 
|  1402 ** the node pNode. This function updates the bounding box cells in |  | 
|  1403 ** all ancestor elements. |  | 
|  1404 */ |  | 
|  1405 static void AdjustTree( |  | 
|  1406   Rtree *pRtree,                    /* Rtree table */ |  | 
|  1407   RtreeNode *pNode,                 /* Adjust ancestry of this node. */ |  | 
|  1408   RtreeCell *pCell                  /* This cell was just inserted */ |  | 
|  1409 ){ |  | 
|  1410   RtreeNode *p = pNode; |  | 
|  1411   while( p->pParent ){ |  | 
|  1412     RtreeCell cell; |  | 
|  1413     RtreeNode *pParent = p->pParent; |  | 
|  1414     int iCell = nodeParentIndex(pRtree, p); |  | 
|  1415  |  | 
|  1416     nodeGetCell(pRtree, pParent, iCell, &cell); |  | 
|  1417     if( !cellContains(pRtree, &cell, pCell) ){ |  | 
|  1418       cellUnion(pRtree, &cell, pCell); |  | 
|  1419       nodeOverwriteCell(pRtree, pParent, &cell, iCell); |  | 
|  1420     } |  | 
|  1421   |  | 
|  1422     p = pParent; |  | 
|  1423   } |  | 
|  1424 } |  | 
|  1425  |  | 
|  1426 /* |  | 
|  1427 ** Write mapping (iRowid->iNode) to the <rtree>_rowid table. |  | 
|  1428 */ |  | 
|  1429 static int rowidWrite(Rtree *pRtree, sqlite3_int64 iRowid, sqlite3_int64 iNode){ |  | 
|  1430   sqlite3_bind_int64(pRtree->pWriteRowid, 1, iRowid); |  | 
|  1431   sqlite3_bind_int64(pRtree->pWriteRowid, 2, iNode); |  | 
|  1432   sqlite3_step(pRtree->pWriteRowid); |  | 
|  1433   return sqlite3_reset(pRtree->pWriteRowid); |  | 
|  1434 } |  | 
|  1435  |  | 
|  1436 /* |  | 
|  1437 ** Write mapping (iNode->iPar) to the <rtree>_parent table. |  | 
|  1438 */ |  | 
|  1439 static int parentWrite(Rtree *pRtree, sqlite3_int64 iNode, sqlite3_int64 iPar){ |  | 
|  1440   sqlite3_bind_int64(pRtree->pWriteParent, 1, iNode); |  | 
|  1441   sqlite3_bind_int64(pRtree->pWriteParent, 2, iPar); |  | 
|  1442   sqlite3_step(pRtree->pWriteParent); |  | 
|  1443   return sqlite3_reset(pRtree->pWriteParent); |  | 
|  1444 } |  | 
|  1445  |  | 
|  1446 static int rtreeInsertCell(Rtree *, RtreeNode *, RtreeCell *, int); |  | 
|  1447  |  | 
|  1448 #if VARIANT_GUTTMAN_LINEAR_SPLIT |  | 
|  1449 /* |  | 
|  1450 ** Implementation of the linear variant of the PickNext() function from |  | 
|  1451 ** Guttman[84]. |  | 
|  1452 */ |  | 
|  1453 static RtreeCell *LinearPickNext( |  | 
|  1454   Rtree *pRtree, |  | 
|  1455   RtreeCell *aCell,  |  | 
|  1456   int nCell,  |  | 
|  1457   RtreeCell *pLeftBox,  |  | 
|  1458   RtreeCell *pRightBox, |  | 
|  1459   int *aiUsed |  | 
|  1460 ){ |  | 
|  1461   int ii; |  | 
|  1462   for(ii=0; aiUsed[ii]; ii++); |  | 
|  1463   aiUsed[ii] = 1; |  | 
|  1464   return &aCell[ii]; |  | 
|  1465 } |  | 
|  1466  |  | 
|  1467 /* |  | 
|  1468 ** Implementation of the linear variant of the PickSeeds() function from |  | 
|  1469 ** Guttman[84]. |  | 
|  1470 */ |  | 
|  1471 static void LinearPickSeeds( |  | 
|  1472   Rtree *pRtree, |  | 
|  1473   RtreeCell *aCell,  |  | 
|  1474   int nCell,  |  | 
|  1475   int *piLeftSeed,  |  | 
|  1476   int *piRightSeed |  | 
|  1477 ){ |  | 
|  1478   int i; |  | 
|  1479   int iLeftSeed = 0; |  | 
|  1480   int iRightSeed = 1; |  | 
|  1481   float maxNormalInnerWidth = 0.0; |  | 
|  1482  |  | 
|  1483   /* Pick two "seed" cells from the array of cells. The algorithm used |  | 
|  1484   ** here is the LinearPickSeeds algorithm from Gutman[1984]. The  |  | 
|  1485   ** indices of the two seed cells in the array are stored in local |  | 
|  1486   ** variables iLeftSeek and iRightSeed. |  | 
|  1487   */ |  | 
|  1488   for(i=0; i<pRtree->nDim; i++){ |  | 
|  1489     float x1 = aCell[0].aCoord[i*2]; |  | 
|  1490     float x2 = aCell[0].aCoord[i*2+1]; |  | 
|  1491     float x3 = x1; |  | 
|  1492     float x4 = x2; |  | 
|  1493     int jj; |  | 
|  1494  |  | 
|  1495     int iCellLeft = 0; |  | 
|  1496     int iCellRight = 0; |  | 
|  1497  |  | 
|  1498     for(jj=1; jj<nCell; jj++){ |  | 
|  1499       float left = aCell[jj].aCoord[i*2]; |  | 
|  1500       float right = aCell[jj].aCoord[i*2+1]; |  | 
|  1501  |  | 
|  1502       if( left<x1 ) x1 = left; |  | 
|  1503       if( right>x4 ) x4 = right; |  | 
|  1504       if( left>x3 ){ |  | 
|  1505         x3 = left; |  | 
|  1506         iCellRight = jj; |  | 
|  1507       } |  | 
|  1508       if( right<x2 ){ |  | 
|  1509         x2 = right; |  | 
|  1510         iCellLeft = jj; |  | 
|  1511       } |  | 
|  1512     } |  | 
|  1513  |  | 
|  1514     if( x4!=x1 ){ |  | 
|  1515       float normalwidth = (x3 - x2) / (x4 - x1); |  | 
|  1516       if( normalwidth>maxNormalInnerWidth ){ |  | 
|  1517         iLeftSeed = iCellLeft; |  | 
|  1518         iRightSeed = iCellRight; |  | 
|  1519       } |  | 
|  1520     } |  | 
|  1521   } |  | 
|  1522  |  | 
|  1523   *piLeftSeed = iLeftSeed; |  | 
|  1524   *piRightSeed = iRightSeed; |  | 
|  1525 } |  | 
|  1526 #endif /* VARIANT_GUTTMAN_LINEAR_SPLIT */ |  | 
|  1527  |  | 
|  1528 #if VARIANT_GUTTMAN_QUADRATIC_SPLIT |  | 
|  1529 /* |  | 
|  1530 ** Implementation of the quadratic variant of the PickNext() function from |  | 
|  1531 ** Guttman[84]. |  | 
|  1532 */ |  | 
|  1533 static RtreeCell *QuadraticPickNext( |  | 
|  1534   Rtree *pRtree, |  | 
|  1535   RtreeCell *aCell,  |  | 
|  1536   int nCell,  |  | 
|  1537   RtreeCell *pLeftBox,  |  | 
|  1538   RtreeCell *pRightBox, |  | 
|  1539   int *aiUsed |  | 
|  1540 ){ |  | 
|  1541   #define FABS(a) ((a)<0.0?-1.0*(a):(a)) |  | 
|  1542  |  | 
|  1543   int iSelect = -1; |  | 
|  1544   float fDiff; |  | 
|  1545   int ii; |  | 
|  1546   for(ii=0; ii<nCell; ii++){ |  | 
|  1547     if( aiUsed[ii]==0 ){ |  | 
|  1548       float left = cellGrowth(pRtree, pLeftBox, &aCell[ii]); |  | 
|  1549       float right = cellGrowth(pRtree, pLeftBox, &aCell[ii]); |  | 
|  1550       float diff = FABS(right-left); |  | 
|  1551       if( iSelect<0 || diff>fDiff ){ |  | 
|  1552         fDiff = diff; |  | 
|  1553         iSelect = ii; |  | 
|  1554       } |  | 
|  1555     } |  | 
|  1556   } |  | 
|  1557   aiUsed[iSelect] = 1; |  | 
|  1558   return &aCell[iSelect]; |  | 
|  1559 } |  | 
|  1560  |  | 
|  1561 /* |  | 
|  1562 ** Implementation of the quadratic variant of the PickSeeds() function from |  | 
|  1563 ** Guttman[84]. |  | 
|  1564 */ |  | 
|  1565 static void QuadraticPickSeeds( |  | 
|  1566   Rtree *pRtree, |  | 
|  1567   RtreeCell *aCell,  |  | 
|  1568   int nCell,  |  | 
|  1569   int *piLeftSeed,  |  | 
|  1570   int *piRightSeed |  | 
|  1571 ){ |  | 
|  1572   int ii; |  | 
|  1573   int jj; |  | 
|  1574  |  | 
|  1575   int iLeftSeed = 0; |  | 
|  1576   int iRightSeed = 1; |  | 
|  1577   float fWaste = 0.0; |  | 
|  1578  |  | 
|  1579   for(ii=0; ii<nCell; ii++){ |  | 
|  1580     for(jj=ii+1; jj<nCell; jj++){ |  | 
|  1581       float right = cellArea(pRtree, &aCell[jj]); |  | 
|  1582       float growth = cellGrowth(pRtree, &aCell[ii], &aCell[jj]); |  | 
|  1583       float waste = growth - right; |  | 
|  1584  |  | 
|  1585       if( waste>fWaste ){ |  | 
|  1586         iLeftSeed = ii; |  | 
|  1587         iRightSeed = jj; |  | 
|  1588         fWaste = waste; |  | 
|  1589       } |  | 
|  1590     } |  | 
|  1591   } |  | 
|  1592  |  | 
|  1593   *piLeftSeed = iLeftSeed; |  | 
|  1594   *piRightSeed = iRightSeed; |  | 
|  1595 } |  | 
|  1596 #endif /* VARIANT_GUTTMAN_QUADRATIC_SPLIT */ |  | 
|  1597  |  | 
|  1598 /* |  | 
|  1599 ** Arguments aIdx, aDistance and aSpare all point to arrays of size |  | 
|  1600 ** nIdx. The aIdx array contains the set of integers from 0 to  |  | 
|  1601 ** (nIdx-1) in no particular order. This function sorts the values |  | 
|  1602 ** in aIdx according to the indexed values in aDistance. For |  | 
|  1603 ** example, assuming the inputs: |  | 
|  1604 ** |  | 
|  1605 **   aIdx      = { 0,   1,   2,   3 } |  | 
|  1606 **   aDistance = { 5.0, 2.0, 7.0, 6.0 } |  | 
|  1607 ** |  | 
|  1608 ** this function sets the aIdx array to contain: |  | 
|  1609 ** |  | 
|  1610 **   aIdx      = { 0,   1,   2,   3 } |  | 
|  1611 ** |  | 
|  1612 ** The aSpare array is used as temporary working space by the |  | 
|  1613 ** sorting algorithm. |  | 
|  1614 */ |  | 
|  1615 static void SortByDistance( |  | 
|  1616   int *aIdx,  |  | 
|  1617   int nIdx,  |  | 
|  1618   float *aDistance,  |  | 
|  1619   int *aSpare |  | 
|  1620 ){ |  | 
|  1621   if( nIdx>1 ){ |  | 
|  1622     int iLeft = 0; |  | 
|  1623     int iRight = 0; |  | 
|  1624  |  | 
|  1625     int nLeft = nIdx/2; |  | 
|  1626     int nRight = nIdx-nLeft; |  | 
|  1627     int *aLeft = aIdx; |  | 
|  1628     int *aRight = &aIdx[nLeft]; |  | 
|  1629  |  | 
|  1630     SortByDistance(aLeft, nLeft, aDistance, aSpare); |  | 
|  1631     SortByDistance(aRight, nRight, aDistance, aSpare); |  | 
|  1632  |  | 
|  1633     memcpy(aSpare, aLeft, sizeof(int)*nLeft); |  | 
|  1634     aLeft = aSpare; |  | 
|  1635  |  | 
|  1636     while( iLeft<nLeft || iRight<nRight ){ |  | 
|  1637       if( iLeft==nLeft ){ |  | 
|  1638         aIdx[iLeft+iRight] = aRight[iRight]; |  | 
|  1639         iRight++; |  | 
|  1640       }else if( iRight==nRight ){ |  | 
|  1641         aIdx[iLeft+iRight] = aLeft[iLeft]; |  | 
|  1642         iLeft++; |  | 
|  1643       }else{ |  | 
|  1644         float fLeft = aDistance[aLeft[iLeft]]; |  | 
|  1645         float fRight = aDistance[aRight[iRight]]; |  | 
|  1646         if( fLeft<fRight ){ |  | 
|  1647           aIdx[iLeft+iRight] = aLeft[iLeft]; |  | 
|  1648           iLeft++; |  | 
|  1649         }else{ |  | 
|  1650           aIdx[iLeft+iRight] = aRight[iRight]; |  | 
|  1651           iRight++; |  | 
|  1652         } |  | 
|  1653       } |  | 
|  1654     } |  | 
|  1655  |  | 
|  1656 #if 0 |  | 
|  1657     /* Check that the sort worked */ |  | 
|  1658     { |  | 
|  1659       int jj; |  | 
|  1660       for(jj=1; jj<nIdx; jj++){ |  | 
|  1661         float left = aDistance[aIdx[jj-1]]; |  | 
|  1662         float right = aDistance[aIdx[jj]]; |  | 
|  1663         assert( left<=right ); |  | 
|  1664       } |  | 
|  1665     } |  | 
|  1666 #endif |  | 
|  1667   } |  | 
|  1668 } |  | 
|  1669  |  | 
|  1670 /* |  | 
|  1671 ** Arguments aIdx, aCell and aSpare all point to arrays of size |  | 
|  1672 ** nIdx. The aIdx array contains the set of integers from 0 to  |  | 
|  1673 ** (nIdx-1) in no particular order. This function sorts the values |  | 
|  1674 ** in aIdx according to dimension iDim of the cells in aCell. The |  | 
|  1675 ** minimum value of dimension iDim is considered first, the |  | 
|  1676 ** maximum used to break ties. |  | 
|  1677 ** |  | 
|  1678 ** The aSpare array is used as temporary working space by the |  | 
|  1679 ** sorting algorithm. |  | 
|  1680 */ |  | 
|  1681 static void SortByDimension( |  | 
|  1682   Rtree *pRtree, |  | 
|  1683   int *aIdx,  |  | 
|  1684   int nIdx,  |  | 
|  1685   int iDim,  |  | 
|  1686   RtreeCell *aCell,  |  | 
|  1687   int *aSpare |  | 
|  1688 ){ |  | 
|  1689   if( nIdx>1 ){ |  | 
|  1690  |  | 
|  1691     int iLeft = 0; |  | 
|  1692     int iRight = 0; |  | 
|  1693  |  | 
|  1694     int nLeft = nIdx/2; |  | 
|  1695     int nRight = nIdx-nLeft; |  | 
|  1696     int *aLeft = aIdx; |  | 
|  1697     int *aRight = &aIdx[nLeft]; |  | 
|  1698  |  | 
|  1699     SortByDimension(pRtree, aLeft, nLeft, iDim, aCell, aSpare); |  | 
|  1700     SortByDimension(pRtree, aRight, nRight, iDim, aCell, aSpare); |  | 
|  1701  |  | 
|  1702     memcpy(aSpare, aLeft, sizeof(int)*nLeft); |  | 
|  1703     aLeft = aSpare; |  | 
|  1704     while( iLeft<nLeft || iRight<nRight ){ |  | 
|  1705       double xleft1 = DCOORD(aCell[aLeft[iLeft]].aCoord[iDim*2]); |  | 
|  1706       double xleft2 = DCOORD(aCell[aLeft[iLeft]].aCoord[iDim*2+1]); |  | 
|  1707       double xright1 = DCOORD(aCell[aRight[iRight]].aCoord[iDim*2]); |  | 
|  1708       double xright2 = DCOORD(aCell[aRight[iRight]].aCoord[iDim*2+1]); |  | 
|  1709       if( (iLeft!=nLeft) && ((iRight==nRight) |  | 
|  1710        || (xleft1<xright1) |  | 
|  1711        || (xleft1==xright1 && xleft2<xright2) |  | 
|  1712       )){ |  | 
|  1713         aIdx[iLeft+iRight] = aLeft[iLeft]; |  | 
|  1714         iLeft++; |  | 
|  1715       }else{ |  | 
|  1716         aIdx[iLeft+iRight] = aRight[iRight]; |  | 
|  1717         iRight++; |  | 
|  1718       } |  | 
|  1719     } |  | 
|  1720  |  | 
|  1721 #if 0 |  | 
|  1722     /* Check that the sort worked */ |  | 
|  1723     { |  | 
|  1724       int jj; |  | 
|  1725       for(jj=1; jj<nIdx; jj++){ |  | 
|  1726         float xleft1 = aCell[aIdx[jj-1]].aCoord[iDim*2]; |  | 
|  1727         float xleft2 = aCell[aIdx[jj-1]].aCoord[iDim*2+1]; |  | 
|  1728         float xright1 = aCell[aIdx[jj]].aCoord[iDim*2]; |  | 
|  1729         float xright2 = aCell[aIdx[jj]].aCoord[iDim*2+1]; |  | 
|  1730         assert( xleft1<=xright1 && (xleft1<xright1 || xleft2<=xright2) ); |  | 
|  1731       } |  | 
|  1732     } |  | 
|  1733 #endif |  | 
|  1734   } |  | 
|  1735 } |  | 
|  1736  |  | 
|  1737 #if VARIANT_RSTARTREE_SPLIT |  | 
|  1738 /* |  | 
|  1739 ** Implementation of the R*-tree variant of SplitNode from Beckman[1990]. |  | 
|  1740 */ |  | 
|  1741 static int splitNodeStartree( |  | 
|  1742   Rtree *pRtree, |  | 
|  1743   RtreeCell *aCell, |  | 
|  1744   int nCell, |  | 
|  1745   RtreeNode *pLeft, |  | 
|  1746   RtreeNode *pRight, |  | 
|  1747   RtreeCell *pBboxLeft, |  | 
|  1748   RtreeCell *pBboxRight |  | 
|  1749 ){ |  | 
|  1750   int **aaSorted; |  | 
|  1751   int *aSpare; |  | 
|  1752   int ii; |  | 
|  1753  |  | 
|  1754   int iBestDim; |  | 
|  1755   int iBestSplit; |  | 
|  1756   float fBestMargin; |  | 
|  1757  |  | 
|  1758   int nByte = (pRtree->nDim+1)*(sizeof(int*)+nCell*sizeof(int)); |  | 
|  1759  |  | 
|  1760   aaSorted = (int **)sqlite3_malloc(nByte); |  | 
|  1761   if( !aaSorted ){ |  | 
|  1762     return SQLITE_NOMEM; |  | 
|  1763   } |  | 
|  1764  |  | 
|  1765   aSpare = &((int *)&aaSorted[pRtree->nDim])[pRtree->nDim*nCell]; |  | 
|  1766   memset(aaSorted, 0, nByte); |  | 
|  1767   for(ii=0; ii<pRtree->nDim; ii++){ |  | 
|  1768     int jj; |  | 
|  1769     aaSorted[ii] = &((int *)&aaSorted[pRtree->nDim])[ii*nCell]; |  | 
|  1770     for(jj=0; jj<nCell; jj++){ |  | 
|  1771       aaSorted[ii][jj] = jj; |  | 
|  1772     } |  | 
|  1773     SortByDimension(pRtree, aaSorted[ii], nCell, ii, aCell, aSpare); |  | 
|  1774   } |  | 
|  1775  |  | 
|  1776   for(ii=0; ii<pRtree->nDim; ii++){ |  | 
|  1777     float margin = 0.0; |  | 
|  1778     float fBestOverlap; |  | 
|  1779     float fBestArea; |  | 
|  1780     int iBestLeft; |  | 
|  1781     int nLeft; |  | 
|  1782  |  | 
|  1783     for( |  | 
|  1784       nLeft=RTREE_MINCELLS(pRtree);  |  | 
|  1785       nLeft<=(nCell-RTREE_MINCELLS(pRtree));  |  | 
|  1786       nLeft++ |  | 
|  1787     ){ |  | 
|  1788       RtreeCell left; |  | 
|  1789       RtreeCell right; |  | 
|  1790       int kk; |  | 
|  1791       float overlap; |  | 
|  1792       float area; |  | 
|  1793  |  | 
|  1794       memcpy(&left, &aCell[aaSorted[ii][0]], sizeof(RtreeCell)); |  | 
|  1795       memcpy(&right, &aCell[aaSorted[ii][nCell-1]], sizeof(RtreeCell)); |  | 
|  1796       for(kk=1; kk<(nCell-1); kk++){ |  | 
|  1797         if( kk<nLeft ){ |  | 
|  1798           cellUnion(pRtree, &left, &aCell[aaSorted[ii][kk]]); |  | 
|  1799         }else{ |  | 
|  1800           cellUnion(pRtree, &right, &aCell[aaSorted[ii][kk]]); |  | 
|  1801         } |  | 
|  1802       } |  | 
|  1803       margin += cellMargin(pRtree, &left); |  | 
|  1804       margin += cellMargin(pRtree, &right); |  | 
|  1805       overlap = cellOverlap(pRtree, &left, &right, 1, -1); |  | 
|  1806       area = cellArea(pRtree, &left) + cellArea(pRtree, &right); |  | 
|  1807       if( (nLeft==RTREE_MINCELLS(pRtree)) |  | 
|  1808        || (overlap<fBestOverlap) |  | 
|  1809        || (overlap==fBestOverlap && area<fBestArea) |  | 
|  1810       ){ |  | 
|  1811         iBestLeft = nLeft; |  | 
|  1812         fBestOverlap = overlap; |  | 
|  1813         fBestArea = area; |  | 
|  1814       } |  | 
|  1815     } |  | 
|  1816  |  | 
|  1817     if( ii==0 || margin<fBestMargin ){ |  | 
|  1818       iBestDim = ii; |  | 
|  1819       fBestMargin = margin; |  | 
|  1820       iBestSplit = iBestLeft; |  | 
|  1821     } |  | 
|  1822   } |  | 
|  1823  |  | 
|  1824   memcpy(pBboxLeft, &aCell[aaSorted[iBestDim][0]], sizeof(RtreeCell)); |  | 
|  1825   memcpy(pBboxRight, &aCell[aaSorted[iBestDim][iBestSplit]], sizeof(RtreeCell)); |  | 
|  1826   for(ii=0; ii<nCell; ii++){ |  | 
|  1827     RtreeNode *pTarget = (ii<iBestSplit)?pLeft:pRight; |  | 
|  1828     RtreeCell *pBbox = (ii<iBestSplit)?pBboxLeft:pBboxRight; |  | 
|  1829     RtreeCell *pCell = &aCell[aaSorted[iBestDim][ii]]; |  | 
|  1830     nodeInsertCell(pRtree, pTarget, pCell); |  | 
|  1831     cellUnion(pRtree, pBbox, pCell); |  | 
|  1832   } |  | 
|  1833  |  | 
|  1834   sqlite3_free(aaSorted); |  | 
|  1835   return SQLITE_OK; |  | 
|  1836 } |  | 
|  1837 #endif |  | 
|  1838  |  | 
|  1839 #if VARIANT_GUTTMAN_SPLIT |  | 
|  1840 /* |  | 
|  1841 ** Implementation of the regular R-tree SplitNode from Guttman[1984]. |  | 
|  1842 */ |  | 
|  1843 static int splitNodeGuttman( |  | 
|  1844   Rtree *pRtree, |  | 
|  1845   RtreeCell *aCell, |  | 
|  1846   int nCell, |  | 
|  1847   RtreeNode *pLeft, |  | 
|  1848   RtreeNode *pRight, |  | 
|  1849   RtreeCell *pBboxLeft, |  | 
|  1850   RtreeCell *pBboxRight |  | 
|  1851 ){ |  | 
|  1852   int iLeftSeed = 0; |  | 
|  1853   int iRightSeed = 1; |  | 
|  1854   int *aiUsed; |  | 
|  1855   int i; |  | 
|  1856  |  | 
|  1857   aiUsed = sqlite3_malloc(sizeof(int)*nCell); |  | 
|  1858   memset(aiUsed, 0, sizeof(int)*nCell); |  | 
|  1859  |  | 
|  1860   PickSeeds(pRtree, aCell, nCell, &iLeftSeed, &iRightSeed); |  | 
|  1861  |  | 
|  1862   memcpy(pBboxLeft, &aCell[iLeftSeed], sizeof(RtreeCell)); |  | 
|  1863   memcpy(pBboxRight, &aCell[iRightSeed], sizeof(RtreeCell)); |  | 
|  1864   nodeInsertCell(pRtree, pLeft, &aCell[iLeftSeed]); |  | 
|  1865   nodeInsertCell(pRtree, pRight, &aCell[iRightSeed]); |  | 
|  1866   aiUsed[iLeftSeed] = 1; |  | 
|  1867   aiUsed[iRightSeed] = 1; |  | 
|  1868  |  | 
|  1869   for(i=nCell-2; i>0; i--){ |  | 
|  1870     RtreeCell *pNext; |  | 
|  1871     pNext = PickNext(pRtree, aCell, nCell, pBboxLeft, pBboxRight, aiUsed); |  | 
|  1872     float diff =   |  | 
|  1873       cellGrowth(pRtree, pBboxLeft, pNext) -  |  | 
|  1874       cellGrowth(pRtree, pBboxRight, pNext) |  | 
|  1875     ; |  | 
|  1876     if( (RTREE_MINCELLS(pRtree)-NCELL(pRight)==i) |  | 
|  1877      || (diff>0.0 && (RTREE_MINCELLS(pRtree)-NCELL(pLeft)!=i)) |  | 
|  1878     ){ |  | 
|  1879       nodeInsertCell(pRtree, pRight, pNext); |  | 
|  1880       cellUnion(pRtree, pBboxRight, pNext); |  | 
|  1881     }else{ |  | 
|  1882       nodeInsertCell(pRtree, pLeft, pNext); |  | 
|  1883       cellUnion(pRtree, pBboxLeft, pNext); |  | 
|  1884     } |  | 
|  1885   } |  | 
|  1886  |  | 
|  1887   sqlite3_free(aiUsed); |  | 
|  1888   return SQLITE_OK; |  | 
|  1889 } |  | 
|  1890 #endif |  | 
|  1891  |  | 
|  1892 static int updateMapping( |  | 
|  1893   Rtree *pRtree,  |  | 
|  1894   i64 iRowid,  |  | 
|  1895   RtreeNode *pNode,  |  | 
|  1896   int iHeight |  | 
|  1897 ){ |  | 
|  1898   int (*xSetMapping)(Rtree *, sqlite3_int64, sqlite3_int64); |  | 
|  1899   xSetMapping = ((iHeight==0)?rowidWrite:parentWrite); |  | 
|  1900   if( iHeight>0 ){ |  | 
|  1901     RtreeNode *pChild = nodeHashLookup(pRtree, iRowid); |  | 
|  1902     if( pChild ){ |  | 
|  1903       nodeRelease(pRtree, pChild->pParent); |  | 
|  1904       nodeReference(pNode); |  | 
|  1905       pChild->pParent = pNode; |  | 
|  1906     } |  | 
|  1907   } |  | 
|  1908   return xSetMapping(pRtree, iRowid, pNode->iNode); |  | 
|  1909 } |  | 
|  1910  |  | 
|  1911 static int SplitNode( |  | 
|  1912   Rtree *pRtree, |  | 
|  1913   RtreeNode *pNode, |  | 
|  1914   RtreeCell *pCell, |  | 
|  1915   int iHeight |  | 
|  1916 ){ |  | 
|  1917   int i; |  | 
|  1918   int newCellIsRight = 0; |  | 
|  1919  |  | 
|  1920   int rc = SQLITE_OK; |  | 
|  1921   int nCell = NCELL(pNode); |  | 
|  1922   RtreeCell *aCell; |  | 
|  1923   int *aiUsed; |  | 
|  1924  |  | 
|  1925   RtreeNode *pLeft = 0; |  | 
|  1926   RtreeNode *pRight = 0; |  | 
|  1927  |  | 
|  1928   RtreeCell leftbbox; |  | 
|  1929   RtreeCell rightbbox; |  | 
|  1930  |  | 
|  1931   /* Allocate an array and populate it with a copy of pCell and  |  | 
|  1932   ** all cells from node pLeft. Then zero the original node. |  | 
|  1933   */ |  | 
|  1934   aCell = sqlite3_malloc((sizeof(RtreeCell)+sizeof(int))*(nCell+1)); |  | 
|  1935   if( !aCell ){ |  | 
|  1936     rc = SQLITE_NOMEM; |  | 
|  1937     goto splitnode_out; |  | 
|  1938   } |  | 
|  1939   aiUsed = (int *)&aCell[nCell+1]; |  | 
|  1940   memset(aiUsed, 0, sizeof(int)*(nCell+1)); |  | 
|  1941   for(i=0; i<nCell; i++){ |  | 
|  1942     nodeGetCell(pRtree, pNode, i, &aCell[i]); |  | 
|  1943   } |  | 
|  1944   nodeZero(pRtree, pNode); |  | 
|  1945   memcpy(&aCell[nCell], pCell, sizeof(RtreeCell)); |  | 
|  1946   nCell++; |  | 
|  1947  |  | 
|  1948   if( pNode->iNode==1 ){ |  | 
|  1949     pRight = nodeNew(pRtree, pNode, 1); |  | 
|  1950     pLeft = nodeNew(pRtree, pNode, 1); |  | 
|  1951     pRtree->iDepth++; |  | 
|  1952     pNode->isDirty = 1; |  | 
|  1953     writeInt16(pNode->zData, pRtree->iDepth); |  | 
|  1954   }else{ |  | 
|  1955     pLeft = pNode; |  | 
|  1956     pRight = nodeNew(pRtree, pLeft->pParent, 1); |  | 
|  1957     nodeReference(pLeft); |  | 
|  1958   } |  | 
|  1959  |  | 
|  1960   if( !pLeft || !pRight ){ |  | 
|  1961     rc = SQLITE_NOMEM; |  | 
|  1962     goto splitnode_out; |  | 
|  1963   } |  | 
|  1964  |  | 
|  1965   memset(pLeft->zData, 0, pRtree->iNodeSize); |  | 
|  1966   memset(pRight->zData, 0, pRtree->iNodeSize); |  | 
|  1967  |  | 
|  1968   rc = AssignCells(pRtree, aCell, nCell, pLeft, pRight, &leftbbox, &rightbbox); |  | 
|  1969   if( rc!=SQLITE_OK ){ |  | 
|  1970     goto splitnode_out; |  | 
|  1971   } |  | 
|  1972  |  | 
|  1973   /* Ensure both child nodes have node numbers assigned to them. */ |  | 
|  1974   if( (0==pRight->iNode && SQLITE_OK!=(rc = nodeWrite(pRtree, pRight))) |  | 
|  1975    || (0==pLeft->iNode && SQLITE_OK!=(rc = nodeWrite(pRtree, pLeft))) |  | 
|  1976   ){ |  | 
|  1977     goto splitnode_out; |  | 
|  1978   } |  | 
|  1979  |  | 
|  1980   rightbbox.iRowid = pRight->iNode; |  | 
|  1981   leftbbox.iRowid = pLeft->iNode; |  | 
|  1982  |  | 
|  1983   if( pNode->iNode==1 ){ |  | 
|  1984     rc = rtreeInsertCell(pRtree, pLeft->pParent, &leftbbox, iHeight+1); |  | 
|  1985     if( rc!=SQLITE_OK ){ |  | 
|  1986       goto splitnode_out; |  | 
|  1987     } |  | 
|  1988   }else{ |  | 
|  1989     RtreeNode *pParent = pLeft->pParent; |  | 
|  1990     int iCell = nodeParentIndex(pRtree, pLeft); |  | 
|  1991     nodeOverwriteCell(pRtree, pParent, &leftbbox, iCell); |  | 
|  1992     AdjustTree(pRtree, pParent, &leftbbox); |  | 
|  1993   } |  | 
|  1994   if( (rc = rtreeInsertCell(pRtree, pRight->pParent, &rightbbox, iHeight+1)) ){ |  | 
|  1995     goto splitnode_out; |  | 
|  1996   } |  | 
|  1997  |  | 
|  1998   for(i=0; i<NCELL(pRight); i++){ |  | 
|  1999     i64 iRowid = nodeGetRowid(pRtree, pRight, i); |  | 
|  2000     rc = updateMapping(pRtree, iRowid, pRight, iHeight); |  | 
|  2001     if( iRowid==pCell->iRowid ){ |  | 
|  2002       newCellIsRight = 1; |  | 
|  2003     } |  | 
|  2004     if( rc!=SQLITE_OK ){ |  | 
|  2005       goto splitnode_out; |  | 
|  2006     } |  | 
|  2007   } |  | 
|  2008   if( pNode->iNode==1 ){ |  | 
|  2009     for(i=0; i<NCELL(pLeft); i++){ |  | 
|  2010       i64 iRowid = nodeGetRowid(pRtree, pLeft, i); |  | 
|  2011       rc = updateMapping(pRtree, iRowid, pLeft, iHeight); |  | 
|  2012       if( rc!=SQLITE_OK ){ |  | 
|  2013         goto splitnode_out; |  | 
|  2014       } |  | 
|  2015     } |  | 
|  2016   }else if( newCellIsRight==0 ){ |  | 
|  2017     rc = updateMapping(pRtree, pCell->iRowid, pLeft, iHeight); |  | 
|  2018   } |  | 
|  2019  |  | 
|  2020   if( rc==SQLITE_OK ){ |  | 
|  2021     rc = nodeRelease(pRtree, pRight); |  | 
|  2022     pRight = 0; |  | 
|  2023   } |  | 
|  2024   if( rc==SQLITE_OK ){ |  | 
|  2025     rc = nodeRelease(pRtree, pLeft); |  | 
|  2026     pLeft = 0; |  | 
|  2027   } |  | 
|  2028  |  | 
|  2029 splitnode_out: |  | 
|  2030   nodeRelease(pRtree, pRight); |  | 
|  2031   nodeRelease(pRtree, pLeft); |  | 
|  2032   sqlite3_free(aCell); |  | 
|  2033   return rc; |  | 
|  2034 } |  | 
|  2035  |  | 
|  2036 static int fixLeafParent(Rtree *pRtree, RtreeNode *pLeaf){ |  | 
|  2037   int rc = SQLITE_OK; |  | 
|  2038   if( pLeaf->iNode!=1 && pLeaf->pParent==0 ){ |  | 
|  2039     sqlite3_bind_int64(pRtree->pReadParent, 1, pLeaf->iNode); |  | 
|  2040     if( sqlite3_step(pRtree->pReadParent)==SQLITE_ROW ){ |  | 
|  2041       i64 iNode = sqlite3_column_int64(pRtree->pReadParent, 0); |  | 
|  2042       rc = nodeAcquire(pRtree, iNode, 0, &pLeaf->pParent); |  | 
|  2043     }else{ |  | 
|  2044       rc = SQLITE_ERROR; |  | 
|  2045     } |  | 
|  2046     sqlite3_reset(pRtree->pReadParent); |  | 
|  2047     if( rc==SQLITE_OK ){ |  | 
|  2048       rc = fixLeafParent(pRtree, pLeaf->pParent); |  | 
|  2049     } |  | 
|  2050   } |  | 
|  2051   return rc; |  | 
|  2052 } |  | 
|  2053  |  | 
|  2054 static int deleteCell(Rtree *, RtreeNode *, int, int); |  | 
|  2055  |  | 
|  2056 static int removeNode(Rtree *pRtree, RtreeNode *pNode, int iHeight){ |  | 
|  2057   int rc; |  | 
|  2058   RtreeNode *pParent; |  | 
|  2059   int iCell; |  | 
|  2060  |  | 
|  2061   assert( pNode->nRef==1 ); |  | 
|  2062  |  | 
|  2063   /* Remove the entry in the parent cell. */ |  | 
|  2064   iCell = nodeParentIndex(pRtree, pNode); |  | 
|  2065   pParent = pNode->pParent; |  | 
|  2066   pNode->pParent = 0; |  | 
|  2067   if( SQLITE_OK!=(rc = deleteCell(pRtree, pParent, iCell, iHeight+1))  |  | 
|  2068    || SQLITE_OK!=(rc = nodeRelease(pRtree, pParent)) |  | 
|  2069   ){ |  | 
|  2070     return rc; |  | 
|  2071   } |  | 
|  2072  |  | 
|  2073   /* Remove the xxx_node entry. */ |  | 
|  2074   sqlite3_bind_int64(pRtree->pDeleteNode, 1, pNode->iNode); |  | 
|  2075   sqlite3_step(pRtree->pDeleteNode); |  | 
|  2076   if( SQLITE_OK!=(rc = sqlite3_reset(pRtree->pDeleteNode)) ){ |  | 
|  2077     return rc; |  | 
|  2078   } |  | 
|  2079  |  | 
|  2080   /* Remove the xxx_parent entry. */ |  | 
|  2081   sqlite3_bind_int64(pRtree->pDeleteParent, 1, pNode->iNode); |  | 
|  2082   sqlite3_step(pRtree->pDeleteParent); |  | 
|  2083   if( SQLITE_OK!=(rc = sqlite3_reset(pRtree->pDeleteParent)) ){ |  | 
|  2084     return rc; |  | 
|  2085   } |  | 
|  2086    |  | 
|  2087   /* Remove the node from the in-memory hash table and link it into |  | 
|  2088   ** the Rtree.pDeleted list. Its contents will be re-inserted later on. |  | 
|  2089   */ |  | 
|  2090   nodeHashDelete(pRtree, pNode); |  | 
|  2091   pNode->iNode = iHeight; |  | 
|  2092   pNode->pNext = pRtree->pDeleted; |  | 
|  2093   pNode->nRef++; |  | 
|  2094   pRtree->pDeleted = pNode; |  | 
|  2095  |  | 
|  2096   return SQLITE_OK; |  | 
|  2097 } |  | 
|  2098  |  | 
|  2099 static void fixBoundingBox(Rtree *pRtree, RtreeNode *pNode){ |  | 
|  2100   RtreeNode *pParent = pNode->pParent; |  | 
|  2101   if( pParent ){ |  | 
|  2102     int ii;  |  | 
|  2103     int nCell = NCELL(pNode); |  | 
|  2104     RtreeCell box;                            /* Bounding box for pNode */ |  | 
|  2105     nodeGetCell(pRtree, pNode, 0, &box); |  | 
|  2106     for(ii=1; ii<nCell; ii++){ |  | 
|  2107       RtreeCell cell; |  | 
|  2108       nodeGetCell(pRtree, pNode, ii, &cell); |  | 
|  2109       cellUnion(pRtree, &box, &cell); |  | 
|  2110     } |  | 
|  2111     box.iRowid = pNode->iNode; |  | 
|  2112     ii = nodeParentIndex(pRtree, pNode); |  | 
|  2113     nodeOverwriteCell(pRtree, pParent, &box, ii); |  | 
|  2114     fixBoundingBox(pRtree, pParent); |  | 
|  2115   } |  | 
|  2116 } |  | 
|  2117  |  | 
|  2118 /* |  | 
|  2119 ** Delete the cell at index iCell of node pNode. After removing the |  | 
|  2120 ** cell, adjust the r-tree data structure if required. |  | 
|  2121 */ |  | 
|  2122 static int deleteCell(Rtree *pRtree, RtreeNode *pNode, int iCell, int iHeight){ |  | 
|  2123   int rc; |  | 
|  2124  |  | 
|  2125   if( SQLITE_OK!=(rc = fixLeafParent(pRtree, pNode)) ){ |  | 
|  2126     return rc; |  | 
|  2127   } |  | 
|  2128  |  | 
|  2129   /* Remove the cell from the node. This call just moves bytes around |  | 
|  2130   ** the in-memory node image, so it cannot fail. |  | 
|  2131   */ |  | 
|  2132   nodeDeleteCell(pRtree, pNode, iCell); |  | 
|  2133  |  | 
|  2134   /* If the node is not the tree root and now has less than the minimum |  | 
|  2135   ** number of cells, remove it from the tree. Otherwise, update the |  | 
|  2136   ** cell in the parent node so that it tightly contains the updated |  | 
|  2137   ** node. |  | 
|  2138   */ |  | 
|  2139   if( pNode->iNode!=1 ){ |  | 
|  2140     RtreeNode *pParent = pNode->pParent; |  | 
|  2141     if( (pParent->iNode!=1 || NCELL(pParent)!=1)  |  | 
|  2142      && (NCELL(pNode)<RTREE_MINCELLS(pRtree)) |  | 
|  2143     ){ |  | 
|  2144       rc = removeNode(pRtree, pNode, iHeight); |  | 
|  2145     }else{ |  | 
|  2146       fixBoundingBox(pRtree, pNode); |  | 
|  2147     } |  | 
|  2148   } |  | 
|  2149  |  | 
|  2150   return rc; |  | 
|  2151 } |  | 
|  2152  |  | 
|  2153 static int Reinsert( |  | 
|  2154   Rtree *pRtree,  |  | 
|  2155   RtreeNode *pNode,  |  | 
|  2156   RtreeCell *pCell,  |  | 
|  2157   int iHeight |  | 
|  2158 ){ |  | 
|  2159   int *aOrder; |  | 
|  2160   int *aSpare; |  | 
|  2161   RtreeCell *aCell; |  | 
|  2162   float *aDistance; |  | 
|  2163   int nCell; |  | 
|  2164   float aCenterCoord[RTREE_MAX_DIMENSIONS]; |  | 
|  2165   int iDim; |  | 
|  2166   int ii; |  | 
|  2167   int rc = SQLITE_OK; |  | 
|  2168  |  | 
|  2169   memset(aCenterCoord, 0, sizeof(float)*RTREE_MAX_DIMENSIONS); |  | 
|  2170  |  | 
|  2171   nCell = NCELL(pNode)+1; |  | 
|  2172  |  | 
|  2173   /* Allocate the buffers used by this operation. The allocation is |  | 
|  2174   ** relinquished before this function returns. |  | 
|  2175   */ |  | 
|  2176   aCell = (RtreeCell *)sqlite3_malloc(nCell * ( |  | 
|  2177     sizeof(RtreeCell) +         /* aCell array */ |  | 
|  2178     sizeof(int)       +         /* aOrder array */ |  | 
|  2179     sizeof(int)       +         /* aSpare array */ |  | 
|  2180     sizeof(float)               /* aDistance array */ |  | 
|  2181   )); |  | 
|  2182   if( !aCell ){ |  | 
|  2183     return SQLITE_NOMEM; |  | 
|  2184   } |  | 
|  2185   aOrder    = (int *)&aCell[nCell]; |  | 
|  2186   aSpare    = (int *)&aOrder[nCell]; |  | 
|  2187   aDistance = (float *)&aSpare[nCell]; |  | 
|  2188  |  | 
|  2189   for(ii=0; ii<nCell; ii++){ |  | 
|  2190     if( ii==(nCell-1) ){ |  | 
|  2191       memcpy(&aCell[ii], pCell, sizeof(RtreeCell)); |  | 
|  2192     }else{ |  | 
|  2193       nodeGetCell(pRtree, pNode, ii, &aCell[ii]); |  | 
|  2194     } |  | 
|  2195     aOrder[ii] = ii; |  | 
|  2196     for(iDim=0; iDim<pRtree->nDim; iDim++){ |  | 
|  2197       aCenterCoord[iDim] += DCOORD(aCell[ii].aCoord[iDim*2]); |  | 
|  2198       aCenterCoord[iDim] += DCOORD(aCell[ii].aCoord[iDim*2+1]); |  | 
|  2199     } |  | 
|  2200   } |  | 
|  2201   for(iDim=0; iDim<pRtree->nDim; iDim++){ |  | 
|  2202     aCenterCoord[iDim] = aCenterCoord[iDim]/((float)nCell*2.0); |  | 
|  2203   } |  | 
|  2204  |  | 
|  2205   for(ii=0; ii<nCell; ii++){ |  | 
|  2206     aDistance[ii] = 0.0; |  | 
|  2207     for(iDim=0; iDim<pRtree->nDim; iDim++){ |  | 
|  2208       float coord = DCOORD(aCell[ii].aCoord[iDim*2+1]) -  |  | 
|  2209           DCOORD(aCell[ii].aCoord[iDim*2]); |  | 
|  2210       aDistance[ii] += (coord-aCenterCoord[iDim])*(coord-aCenterCoord[iDim]); |  | 
|  2211     } |  | 
|  2212   } |  | 
|  2213  |  | 
|  2214   SortByDistance(aOrder, nCell, aDistance, aSpare); |  | 
|  2215   nodeZero(pRtree, pNode); |  | 
|  2216  |  | 
|  2217   for(ii=0; rc==SQLITE_OK && ii<(nCell-(RTREE_MINCELLS(pRtree)+1)); ii++){ |  | 
|  2218     RtreeCell *p = &aCell[aOrder[ii]]; |  | 
|  2219     nodeInsertCell(pRtree, pNode, p); |  | 
|  2220     if( p->iRowid==pCell->iRowid ){ |  | 
|  2221       if( iHeight==0 ){ |  | 
|  2222         rc = rowidWrite(pRtree, p->iRowid, pNode->iNode); |  | 
|  2223       }else{ |  | 
|  2224         rc = parentWrite(pRtree, p->iRowid, pNode->iNode); |  | 
|  2225       } |  | 
|  2226     } |  | 
|  2227   } |  | 
|  2228   if( rc==SQLITE_OK ){ |  | 
|  2229     fixBoundingBox(pRtree, pNode); |  | 
|  2230   } |  | 
|  2231   for(; rc==SQLITE_OK && ii<nCell; ii++){ |  | 
|  2232     /* Find a node to store this cell in. pNode->iNode currently contains |  | 
|  2233     ** the height of the sub-tree headed by the cell. |  | 
|  2234     */ |  | 
|  2235     RtreeNode *pInsert; |  | 
|  2236     RtreeCell *p = &aCell[aOrder[ii]]; |  | 
|  2237     rc = ChooseLeaf(pRtree, p, iHeight, &pInsert); |  | 
|  2238     if( rc==SQLITE_OK ){ |  | 
|  2239       int rc2; |  | 
|  2240       rc = rtreeInsertCell(pRtree, pInsert, p, iHeight); |  | 
|  2241       rc2 = nodeRelease(pRtree, pInsert); |  | 
|  2242       if( rc==SQLITE_OK ){ |  | 
|  2243         rc = rc2; |  | 
|  2244       } |  | 
|  2245     } |  | 
|  2246   } |  | 
|  2247  |  | 
|  2248   sqlite3_free(aCell); |  | 
|  2249   return rc; |  | 
|  2250 } |  | 
|  2251  |  | 
|  2252 /* |  | 
|  2253 ** Insert cell pCell into node pNode. Node pNode is the head of a  |  | 
|  2254 ** subtree iHeight high (leaf nodes have iHeight==0). |  | 
|  2255 */ |  | 
|  2256 static int rtreeInsertCell( |  | 
|  2257   Rtree *pRtree, |  | 
|  2258   RtreeNode *pNode, |  | 
|  2259   RtreeCell *pCell, |  | 
|  2260   int iHeight |  | 
|  2261 ){ |  | 
|  2262   int rc = SQLITE_OK; |  | 
|  2263   if( iHeight>0 ){ |  | 
|  2264     RtreeNode *pChild = nodeHashLookup(pRtree, pCell->iRowid); |  | 
|  2265     if( pChild ){ |  | 
|  2266       nodeRelease(pRtree, pChild->pParent); |  | 
|  2267       nodeReference(pNode); |  | 
|  2268       pChild->pParent = pNode; |  | 
|  2269     } |  | 
|  2270   } |  | 
|  2271   if( nodeInsertCell(pRtree, pNode, pCell) ){ |  | 
|  2272 #if VARIANT_RSTARTREE_REINSERT |  | 
|  2273     if( iHeight<=pRtree->iReinsertHeight || pNode->iNode==1){ |  | 
|  2274       rc = SplitNode(pRtree, pNode, pCell, iHeight); |  | 
|  2275     }else{ |  | 
|  2276       pRtree->iReinsertHeight = iHeight; |  | 
|  2277       rc = Reinsert(pRtree, pNode, pCell, iHeight); |  | 
|  2278     } |  | 
|  2279 #else |  | 
|  2280     rc = SplitNode(pRtree, pNode, pCell, iHeight); |  | 
|  2281 #endif |  | 
|  2282   }else{ |  | 
|  2283     AdjustTree(pRtree, pNode, pCell); |  | 
|  2284     if( iHeight==0 ){ |  | 
|  2285       rc = rowidWrite(pRtree, pCell->iRowid, pNode->iNode); |  | 
|  2286     }else{ |  | 
|  2287       rc = parentWrite(pRtree, pCell->iRowid, pNode->iNode); |  | 
|  2288     } |  | 
|  2289   } |  | 
|  2290   return rc; |  | 
|  2291 } |  | 
|  2292  |  | 
|  2293 static int reinsertNodeContent(Rtree *pRtree, RtreeNode *pNode){ |  | 
|  2294   int ii; |  | 
|  2295   int rc = SQLITE_OK; |  | 
|  2296   int nCell = NCELL(pNode); |  | 
|  2297  |  | 
|  2298   for(ii=0; rc==SQLITE_OK && ii<nCell; ii++){ |  | 
|  2299     RtreeNode *pInsert; |  | 
|  2300     RtreeCell cell; |  | 
|  2301     nodeGetCell(pRtree, pNode, ii, &cell); |  | 
|  2302  |  | 
|  2303     /* Find a node to store this cell in. pNode->iNode currently contains |  | 
|  2304     ** the height of the sub-tree headed by the cell. |  | 
|  2305     */ |  | 
|  2306     rc = ChooseLeaf(pRtree, &cell, pNode->iNode, &pInsert); |  | 
|  2307     if( rc==SQLITE_OK ){ |  | 
|  2308       int rc2; |  | 
|  2309       rc = rtreeInsertCell(pRtree, pInsert, &cell, pNode->iNode); |  | 
|  2310       rc2 = nodeRelease(pRtree, pInsert); |  | 
|  2311       if( rc==SQLITE_OK ){ |  | 
|  2312         rc = rc2; |  | 
|  2313       } |  | 
|  2314     } |  | 
|  2315   } |  | 
|  2316   return rc; |  | 
|  2317 } |  | 
|  2318  |  | 
|  2319 /* |  | 
|  2320 ** Select a currently unused rowid for a new r-tree record. |  | 
|  2321 */ |  | 
|  2322 static int newRowid(Rtree *pRtree, i64 *piRowid){ |  | 
|  2323   int rc; |  | 
|  2324   sqlite3_bind_null(pRtree->pWriteRowid, 1); |  | 
|  2325   sqlite3_bind_null(pRtree->pWriteRowid, 2); |  | 
|  2326   sqlite3_step(pRtree->pWriteRowid); |  | 
|  2327   rc = sqlite3_reset(pRtree->pWriteRowid); |  | 
|  2328   *piRowid = sqlite3_last_insert_rowid(pRtree->db); |  | 
|  2329   return rc; |  | 
|  2330 } |  | 
|  2331  |  | 
|  2332 #ifndef NDEBUG |  | 
|  2333 static int hashIsEmpty(Rtree *pRtree){ |  | 
|  2334   int ii; |  | 
|  2335   for(ii=0; ii<HASHSIZE; ii++){ |  | 
|  2336     assert( !pRtree->aHash[ii] ); |  | 
|  2337   } |  | 
|  2338   return 1; |  | 
|  2339 } |  | 
|  2340 #endif |  | 
|  2341  |  | 
|  2342 /* |  | 
|  2343 ** The xUpdate method for rtree module virtual tables. |  | 
|  2344 */ |  | 
|  2345 static int rtreeUpdate( |  | 
|  2346   sqlite3_vtab *pVtab,  |  | 
|  2347   int nData,  |  | 
|  2348   sqlite3_value **azData,  |  | 
|  2349   sqlite_int64 *pRowid |  | 
|  2350 ){ |  | 
|  2351   Rtree *pRtree = (Rtree *)pVtab; |  | 
|  2352   int rc = SQLITE_OK; |  | 
|  2353  |  | 
|  2354   rtreeReference(pRtree); |  | 
|  2355  |  | 
|  2356   assert(nData>=1); |  | 
|  2357   assert(hashIsEmpty(pRtree)); |  | 
|  2358  |  | 
|  2359   /* If azData[0] is not an SQL NULL value, it is the rowid of a |  | 
|  2360   ** record to delete from the r-tree table. The following block does |  | 
|  2361   ** just that. |  | 
|  2362   */ |  | 
|  2363   if( sqlite3_value_type(azData[0])!=SQLITE_NULL ){ |  | 
|  2364     i64 iDelete;                /* The rowid to delete */ |  | 
|  2365     RtreeNode *pLeaf;           /* Leaf node containing record iDelete */ |  | 
|  2366     int iCell;                  /* Index of iDelete cell in pLeaf */ |  | 
|  2367     RtreeNode *pRoot; |  | 
|  2368  |  | 
|  2369     /* Obtain a reference to the root node to initialise Rtree.iDepth */ |  | 
|  2370     rc = nodeAcquire(pRtree, 1, 0, &pRoot); |  | 
|  2371  |  | 
|  2372     /* Obtain a reference to the leaf node that contains the entry  |  | 
|  2373     ** about to be deleted.  |  | 
|  2374     */ |  | 
|  2375     if( rc==SQLITE_OK ){ |  | 
|  2376       iDelete = sqlite3_value_int64(azData[0]); |  | 
|  2377       rc = findLeafNode(pRtree, iDelete, &pLeaf); |  | 
|  2378     } |  | 
|  2379  |  | 
|  2380     /* Delete the cell in question from the leaf node. */ |  | 
|  2381     if( rc==SQLITE_OK ){ |  | 
|  2382       int rc2; |  | 
|  2383       iCell = nodeRowidIndex(pRtree, pLeaf, iDelete); |  | 
|  2384       rc = deleteCell(pRtree, pLeaf, iCell, 0); |  | 
|  2385       rc2 = nodeRelease(pRtree, pLeaf); |  | 
|  2386       if( rc==SQLITE_OK ){ |  | 
|  2387         rc = rc2; |  | 
|  2388       } |  | 
|  2389     } |  | 
|  2390  |  | 
|  2391     /* Delete the corresponding entry in the <rtree>_rowid table. */ |  | 
|  2392     if( rc==SQLITE_OK ){ |  | 
|  2393       sqlite3_bind_int64(pRtree->pDeleteRowid, 1, iDelete); |  | 
|  2394       sqlite3_step(pRtree->pDeleteRowid); |  | 
|  2395       rc = sqlite3_reset(pRtree->pDeleteRowid); |  | 
|  2396     } |  | 
|  2397  |  | 
|  2398     /* Check if the root node now has exactly one child. If so, remove |  | 
|  2399     ** it, schedule the contents of the child for reinsertion and  |  | 
|  2400     ** reduce the tree height by one. |  | 
|  2401     ** |  | 
|  2402     ** This is equivalent to copying the contents of the child into |  | 
|  2403     ** the root node (the operation that Gutman's paper says to perform  |  | 
|  2404     ** in this scenario). |  | 
|  2405     */ |  | 
|  2406     if( rc==SQLITE_OK && pRtree->iDepth>0 ){ |  | 
|  2407       if( rc==SQLITE_OK && NCELL(pRoot)==1 ){ |  | 
|  2408         RtreeNode *pChild; |  | 
|  2409         i64 iChild = nodeGetRowid(pRtree, pRoot, 0); |  | 
|  2410         rc = nodeAcquire(pRtree, iChild, pRoot, &pChild); |  | 
|  2411         if( rc==SQLITE_OK ){ |  | 
|  2412           rc = removeNode(pRtree, pChild, pRtree->iDepth-1); |  | 
|  2413         } |  | 
|  2414         if( rc==SQLITE_OK ){ |  | 
|  2415           pRtree->iDepth--; |  | 
|  2416           writeInt16(pRoot->zData, pRtree->iDepth); |  | 
|  2417           pRoot->isDirty = 1; |  | 
|  2418         } |  | 
|  2419       } |  | 
|  2420     } |  | 
|  2421  |  | 
|  2422     /* Re-insert the contents of any underfull nodes removed from the tree. */ |  | 
|  2423     for(pLeaf=pRtree->pDeleted; pLeaf; pLeaf=pRtree->pDeleted){ |  | 
|  2424       if( rc==SQLITE_OK ){ |  | 
|  2425         rc = reinsertNodeContent(pRtree, pLeaf); |  | 
|  2426       } |  | 
|  2427       pRtree->pDeleted = pLeaf->pNext; |  | 
|  2428       sqlite3_free(pLeaf); |  | 
|  2429     } |  | 
|  2430  |  | 
|  2431     /* Release the reference to the root node. */ |  | 
|  2432     if( rc==SQLITE_OK ){ |  | 
|  2433       rc = nodeRelease(pRtree, pRoot); |  | 
|  2434     }else{ |  | 
|  2435       nodeRelease(pRtree, pRoot); |  | 
|  2436     } |  | 
|  2437   } |  | 
|  2438  |  | 
|  2439   /* If the azData[] array contains more than one element, elements |  | 
|  2440   ** (azData[2]..azData[argc-1]) contain a new record to insert into |  | 
|  2441   ** the r-tree structure. |  | 
|  2442   */ |  | 
|  2443   if( rc==SQLITE_OK && nData>1 ){ |  | 
|  2444     /* Insert a new record into the r-tree */ |  | 
|  2445     RtreeCell cell; |  | 
|  2446     int ii; |  | 
|  2447     RtreeNode *pLeaf; |  | 
|  2448  |  | 
|  2449     /* Populate the cell.aCoord[] array. The first coordinate is azData[3]. */ |  | 
|  2450     assert( nData==(pRtree->nDim*2 + 3) ); |  | 
|  2451     if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ |  | 
|  2452       for(ii=0; ii<(pRtree->nDim*2); ii+=2){ |  | 
|  2453         cell.aCoord[ii].f = (float)sqlite3_value_double(azData[ii+3]); |  | 
|  2454         cell.aCoord[ii+1].f = (float)sqlite3_value_double(azData[ii+4]); |  | 
|  2455         if( cell.aCoord[ii].f>cell.aCoord[ii+1].f ){ |  | 
|  2456           rc = SQLITE_CONSTRAINT; |  | 
|  2457           goto constraint; |  | 
|  2458         } |  | 
|  2459       } |  | 
|  2460     }else{ |  | 
|  2461       for(ii=0; ii<(pRtree->nDim*2); ii+=2){ |  | 
|  2462         cell.aCoord[ii].i = sqlite3_value_int(azData[ii+3]); |  | 
|  2463         cell.aCoord[ii+1].i = sqlite3_value_int(azData[ii+4]); |  | 
|  2464         if( cell.aCoord[ii].i>cell.aCoord[ii+1].i ){ |  | 
|  2465           rc = SQLITE_CONSTRAINT; |  | 
|  2466           goto constraint; |  | 
|  2467         } |  | 
|  2468       } |  | 
|  2469     } |  | 
|  2470  |  | 
|  2471     /* Figure out the rowid of the new row. */ |  | 
|  2472     if( sqlite3_value_type(azData[2])==SQLITE_NULL ){ |  | 
|  2473       rc = newRowid(pRtree, &cell.iRowid); |  | 
|  2474     }else{ |  | 
|  2475       cell.iRowid = sqlite3_value_int64(azData[2]); |  | 
|  2476       sqlite3_bind_int64(pRtree->pReadRowid, 1, cell.iRowid); |  | 
|  2477       if( SQLITE_ROW==sqlite3_step(pRtree->pReadRowid) ){ |  | 
|  2478         sqlite3_reset(pRtree->pReadRowid); |  | 
|  2479         rc = SQLITE_CONSTRAINT; |  | 
|  2480         goto constraint; |  | 
|  2481       } |  | 
|  2482       rc = sqlite3_reset(pRtree->pReadRowid); |  | 
|  2483     } |  | 
|  2484  |  | 
|  2485     if( rc==SQLITE_OK ){ |  | 
|  2486       rc = ChooseLeaf(pRtree, &cell, 0, &pLeaf); |  | 
|  2487     } |  | 
|  2488     if( rc==SQLITE_OK ){ |  | 
|  2489       int rc2; |  | 
|  2490       pRtree->iReinsertHeight = -1; |  | 
|  2491       rc = rtreeInsertCell(pRtree, pLeaf, &cell, 0); |  | 
|  2492       rc2 = nodeRelease(pRtree, pLeaf); |  | 
|  2493       if( rc==SQLITE_OK ){ |  | 
|  2494         rc = rc2; |  | 
|  2495       } |  | 
|  2496     } |  | 
|  2497   } |  | 
|  2498  |  | 
|  2499 constraint: |  | 
|  2500   rtreeRelease(pRtree); |  | 
|  2501   return rc; |  | 
|  2502 } |  | 
|  2503  |  | 
|  2504 /* |  | 
|  2505 ** The xRename method for rtree module virtual tables. |  | 
|  2506 */ |  | 
|  2507 static int rtreeRename(sqlite3_vtab *pVtab, const char *zNewName){ |  | 
|  2508   Rtree *pRtree = (Rtree *)pVtab; |  | 
|  2509   int rc = SQLITE_NOMEM; |  | 
|  2510   char *zSql = sqlite3_mprintf( |  | 
|  2511     "ALTER TABLE %Q.'%q_node'   RENAME TO \"%w_node\";" |  | 
|  2512     "ALTER TABLE %Q.'%q_parent' RENAME TO \"%w_parent\";" |  | 
|  2513     "ALTER TABLE %Q.'%q_rowid'  RENAME TO \"%w_rowid\";" |  | 
|  2514     , pRtree->zDb, pRtree->zName, zNewName  |  | 
|  2515     , pRtree->zDb, pRtree->zName, zNewName  |  | 
|  2516     , pRtree->zDb, pRtree->zName, zNewName |  | 
|  2517   ); |  | 
|  2518   if( zSql ){ |  | 
|  2519     rc = sqlite3_exec(pRtree->db, zSql, 0, 0, 0); |  | 
|  2520     sqlite3_free(zSql); |  | 
|  2521   } |  | 
|  2522   return rc; |  | 
|  2523 } |  | 
|  2524  |  | 
|  2525 static sqlite3_module rtreeModule = { |  | 
|  2526   0,                         /* iVersion */ |  | 
|  2527   rtreeCreate,                /* xCreate - create a table */ |  | 
|  2528   rtreeConnect,               /* xConnect - connect to an existing table */ |  | 
|  2529   rtreeBestIndex,             /* xBestIndex - Determine search strategy */ |  | 
|  2530   rtreeDisconnect,            /* xDisconnect - Disconnect from a table */ |  | 
|  2531   rtreeDestroy,               /* xDestroy - Drop a table */ |  | 
|  2532   rtreeOpen,                  /* xOpen - open a cursor */ |  | 
|  2533   rtreeClose,                 /* xClose - close a cursor */ |  | 
|  2534   rtreeFilter,                /* xFilter - configure scan constraints */ |  | 
|  2535   rtreeNext,                  /* xNext - advance a cursor */ |  | 
|  2536   rtreeEof,                   /* xEof */ |  | 
|  2537   rtreeColumn,                /* xColumn - read data */ |  | 
|  2538   rtreeRowid,                 /* xRowid - read data */ |  | 
|  2539   rtreeUpdate,                /* xUpdate - write data */ |  | 
|  2540   0,                          /* xBegin - begin transaction */ |  | 
|  2541   0,                          /* xSync - sync transaction */ |  | 
|  2542   0,                          /* xCommit - commit transaction */ |  | 
|  2543   0,                          /* xRollback - rollback transaction */ |  | 
|  2544   0,                          /* xFindFunction - function overloading */ |  | 
|  2545   rtreeRename                 /* xRename - rename the table */ |  | 
|  2546 }; |  | 
|  2547  |  | 
|  2548 static int rtreeSqlInit( |  | 
|  2549   Rtree *pRtree,  |  | 
|  2550   sqlite3 *db,  |  | 
|  2551   const char *zDb,  |  | 
|  2552   const char *zPrefix,  |  | 
|  2553   int isCreate |  | 
|  2554 ){ |  | 
|  2555   int rc = SQLITE_OK; |  | 
|  2556  |  | 
|  2557   #define N_STATEMENT 9 |  | 
|  2558   static const char *azSql[N_STATEMENT] = { |  | 
|  2559     /* Read and write the xxx_node table */ |  | 
|  2560     "SELECT data FROM '%q'.'%q_node' WHERE nodeno = :1", |  | 
|  2561     "INSERT OR REPLACE INTO '%q'.'%q_node' VALUES(:1, :2)", |  | 
|  2562     "DELETE FROM '%q'.'%q_node' WHERE nodeno = :1", |  | 
|  2563  |  | 
|  2564     /* Read and write the xxx_rowid table */ |  | 
|  2565     "SELECT nodeno FROM '%q'.'%q_rowid' WHERE rowid = :1", |  | 
|  2566     "INSERT OR REPLACE INTO '%q'.'%q_rowid' VALUES(:1, :2)", |  | 
|  2567     "DELETE FROM '%q'.'%q_rowid' WHERE rowid = :1", |  | 
|  2568  |  | 
|  2569     /* Read and write the xxx_parent table */ |  | 
|  2570     "SELECT parentnode FROM '%q'.'%q_parent' WHERE nodeno = :1", |  | 
|  2571     "INSERT OR REPLACE INTO '%q'.'%q_parent' VALUES(:1, :2)", |  | 
|  2572     "DELETE FROM '%q'.'%q_parent' WHERE nodeno = :1" |  | 
|  2573   }; |  | 
|  2574   sqlite3_stmt **appStmt[N_STATEMENT]; |  | 
|  2575   int i; |  | 
|  2576  |  | 
|  2577   pRtree->db = db; |  | 
|  2578  |  | 
|  2579   if( isCreate ){ |  | 
|  2580     char *zCreate = sqlite3_mprintf( |  | 
|  2581 "CREATE TABLE \"%w\".\"%w_node\"(nodeno INTEGER PRIMARY KEY, data BLOB);" |  | 
|  2582 "CREATE TABLE \"%w\".\"%w_rowid\"(rowid INTEGER PRIMARY KEY, nodeno INTEGER);" |  | 
|  2583 "CREATE TABLE \"%w\".\"%w_parent\"(nodeno INTEGER PRIMARY KEY, parentnode INTEGE
      R);" |  | 
|  2584 "INSERT INTO '%q'.'%q_node' VALUES(1, zeroblob(%d))", |  | 
|  2585       zDb, zPrefix, zDb, zPrefix, zDb, zPrefix, zDb, zPrefix, pRtree->iNodeSize |  | 
|  2586     ); |  | 
|  2587     if( !zCreate ){ |  | 
|  2588       return SQLITE_NOMEM; |  | 
|  2589     } |  | 
|  2590     rc = sqlite3_exec(db, zCreate, 0, 0, 0); |  | 
|  2591     sqlite3_free(zCreate); |  | 
|  2592     if( rc!=SQLITE_OK ){ |  | 
|  2593       return rc; |  | 
|  2594     } |  | 
|  2595   } |  | 
|  2596  |  | 
|  2597   appStmt[0] = &pRtree->pReadNode; |  | 
|  2598   appStmt[1] = &pRtree->pWriteNode; |  | 
|  2599   appStmt[2] = &pRtree->pDeleteNode; |  | 
|  2600   appStmt[3] = &pRtree->pReadRowid; |  | 
|  2601   appStmt[4] = &pRtree->pWriteRowid; |  | 
|  2602   appStmt[5] = &pRtree->pDeleteRowid; |  | 
|  2603   appStmt[6] = &pRtree->pReadParent; |  | 
|  2604   appStmt[7] = &pRtree->pWriteParent; |  | 
|  2605   appStmt[8] = &pRtree->pDeleteParent; |  | 
|  2606  |  | 
|  2607   for(i=0; i<N_STATEMENT && rc==SQLITE_OK; i++){ |  | 
|  2608     char *zSql = sqlite3_mprintf(azSql[i], zDb, zPrefix); |  | 
|  2609     if( zSql ){ |  | 
|  2610       rc = sqlite3_prepare_v2(db, zSql, -1, appStmt[i], 0);  |  | 
|  2611     }else{ |  | 
|  2612       rc = SQLITE_NOMEM; |  | 
|  2613     } |  | 
|  2614     sqlite3_free(zSql); |  | 
|  2615   } |  | 
|  2616  |  | 
|  2617   return rc; |  | 
|  2618 } |  | 
|  2619  |  | 
|  2620 /* |  | 
|  2621 ** This routine queries database handle db for the page-size used by |  | 
|  2622 ** database zDb. If successful, the page-size in bytes is written to |  | 
|  2623 ** *piPageSize and SQLITE_OK returned. Otherwise, and an SQLite error  |  | 
|  2624 ** code is returned. |  | 
|  2625 */ |  | 
|  2626 static int getPageSize(sqlite3 *db, const char *zDb, int *piPageSize){ |  | 
|  2627   int rc = SQLITE_NOMEM; |  | 
|  2628   char *zSql; |  | 
|  2629   sqlite3_stmt *pStmt = 0; |  | 
|  2630  |  | 
|  2631   zSql = sqlite3_mprintf("PRAGMA %Q.page_size", zDb); |  | 
|  2632   if( !zSql ){ |  | 
|  2633     return SQLITE_NOMEM; |  | 
|  2634   } |  | 
|  2635  |  | 
|  2636   rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); |  | 
|  2637   sqlite3_free(zSql); |  | 
|  2638   if( rc!=SQLITE_OK ){ |  | 
|  2639     return rc; |  | 
|  2640   } |  | 
|  2641  |  | 
|  2642   if( SQLITE_ROW==sqlite3_step(pStmt) ){ |  | 
|  2643     *piPageSize = sqlite3_column_int(pStmt, 0); |  | 
|  2644   } |  | 
|  2645   return sqlite3_finalize(pStmt); |  | 
|  2646 } |  | 
|  2647  |  | 
|  2648 /*  |  | 
|  2649 ** This function is the implementation of both the xConnect and xCreate |  | 
|  2650 ** methods of the r-tree virtual table. |  | 
|  2651 ** |  | 
|  2652 **   argv[0]   -> module name |  | 
|  2653 **   argv[1]   -> database name |  | 
|  2654 **   argv[2]   -> table name |  | 
|  2655 **   argv[...] -> column names... |  | 
|  2656 */ |  | 
|  2657 static int rtreeInit( |  | 
|  2658   sqlite3 *db,                        /* Database connection */ |  | 
|  2659   void *pAux,                         /* One of the RTREE_COORD_* constants */ |  | 
|  2660   int argc, const char *const*argv,   /* Parameters to CREATE TABLE statement */ |  | 
|  2661   sqlite3_vtab **ppVtab,              /* OUT: New virtual table */ |  | 
|  2662   char **pzErr,                       /* OUT: Error message, if any */ |  | 
|  2663   int isCreate                        /* True for xCreate, false for xConnect */ |  | 
|  2664 ){ |  | 
|  2665   int rc = SQLITE_OK; |  | 
|  2666   int iPageSize = 0; |  | 
|  2667   Rtree *pRtree; |  | 
|  2668   int nDb;              /* Length of string argv[1] */ |  | 
|  2669   int nName;            /* Length of string argv[2] */ |  | 
|  2670   int eCoordType = (int)pAux; |  | 
|  2671  |  | 
|  2672   const char *aErrMsg[] = { |  | 
|  2673     0,                                                    /* 0 */ |  | 
|  2674     "Wrong number of columns for an rtree table",         /* 1 */ |  | 
|  2675     "Too few columns for an rtree table",                 /* 2 */ |  | 
|  2676     "Too many columns for an rtree table"                 /* 3 */ |  | 
|  2677   }; |  | 
|  2678  |  | 
|  2679   int iErr = (argc<6) ? 2 : argc>(RTREE_MAX_DIMENSIONS*2+4) ? 3 : argc%2; |  | 
|  2680   if( aErrMsg[iErr] ){ |  | 
|  2681     *pzErr = sqlite3_mprintf("%s", aErrMsg[iErr]); |  | 
|  2682     return SQLITE_ERROR; |  | 
|  2683   } |  | 
|  2684  |  | 
|  2685   rc = getPageSize(db, argv[1], &iPageSize); |  | 
|  2686   if( rc!=SQLITE_OK ){ |  | 
|  2687     return rc; |  | 
|  2688   } |  | 
|  2689  |  | 
|  2690   /* Allocate the sqlite3_vtab structure */ |  | 
|  2691   nDb = strlen(argv[1]); |  | 
|  2692   nName = strlen(argv[2]); |  | 
|  2693   pRtree = (Rtree *)sqlite3_malloc(sizeof(Rtree)+nDb+nName+2); |  | 
|  2694   if( !pRtree ){ |  | 
|  2695     return SQLITE_NOMEM; |  | 
|  2696   } |  | 
|  2697   memset(pRtree, 0, sizeof(Rtree)+nDb+nName+2); |  | 
|  2698   pRtree->nBusy = 1; |  | 
|  2699   pRtree->base.pModule = &rtreeModule; |  | 
|  2700   pRtree->zDb = (char *)&pRtree[1]; |  | 
|  2701   pRtree->zName = &pRtree->zDb[nDb+1]; |  | 
|  2702   pRtree->nDim = (argc-4)/2; |  | 
|  2703   pRtree->nBytesPerCell = 8 + pRtree->nDim*4*2; |  | 
|  2704   pRtree->eCoordType = eCoordType; |  | 
|  2705   memcpy(pRtree->zDb, argv[1], nDb); |  | 
|  2706   memcpy(pRtree->zName, argv[2], nName); |  | 
|  2707  |  | 
|  2708   /* Figure out the node size to use. By default, use 64 bytes less than |  | 
|  2709   ** the database page-size. This ensures that each node is stored on |  | 
|  2710   ** a single database page. |  | 
|  2711   ** |  | 
|  2712   ** If the databasd page-size is so large that more than RTREE_MAXCELLS |  | 
|  2713   ** entries would fit in a single node, use a smaller node-size. |  | 
|  2714   */ |  | 
|  2715   pRtree->iNodeSize = iPageSize-64; |  | 
|  2716   if( (4+pRtree->nBytesPerCell*RTREE_MAXCELLS)<pRtree->iNodeSize ){ |  | 
|  2717     pRtree->iNodeSize = 4+pRtree->nBytesPerCell*RTREE_MAXCELLS; |  | 
|  2718   } |  | 
|  2719  |  | 
|  2720   /* Create/Connect to the underlying relational database schema. If |  | 
|  2721   ** that is successful, call sqlite3_declare_vtab() to configure |  | 
|  2722   ** the r-tree table schema. |  | 
|  2723   */ |  | 
|  2724   if( (rc = rtreeSqlInit(pRtree, db, argv[1], argv[2], isCreate)) ){ |  | 
|  2725     *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); |  | 
|  2726   }else{ |  | 
|  2727     char *zSql = sqlite3_mprintf("CREATE TABLE x(%s", argv[3]); |  | 
|  2728     char *zTmp; |  | 
|  2729     int ii; |  | 
|  2730     for(ii=4; zSql && ii<argc; ii++){ |  | 
|  2731       zTmp = zSql; |  | 
|  2732       zSql = sqlite3_mprintf("%s, %s", zTmp, argv[ii]); |  | 
|  2733       sqlite3_free(zTmp); |  | 
|  2734     } |  | 
|  2735     if( zSql ){ |  | 
|  2736       zTmp = zSql; |  | 
|  2737       zSql = sqlite3_mprintf("%s);", zTmp); |  | 
|  2738       sqlite3_free(zTmp); |  | 
|  2739     } |  | 
|  2740     if( !zSql ){ |  | 
|  2741       rc = SQLITE_NOMEM; |  | 
|  2742     }else if( SQLITE_OK!=(rc = sqlite3_declare_vtab(db, zSql)) ){ |  | 
|  2743       *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); |  | 
|  2744     } |  | 
|  2745     sqlite3_free(zSql); |  | 
|  2746   } |  | 
|  2747  |  | 
|  2748   if( rc==SQLITE_OK ){ |  | 
|  2749     *ppVtab = (sqlite3_vtab *)pRtree; |  | 
|  2750   }else{ |  | 
|  2751     rtreeRelease(pRtree); |  | 
|  2752   } |  | 
|  2753   return rc; |  | 
|  2754 } |  | 
|  2755  |  | 
|  2756  |  | 
|  2757 /* |  | 
|  2758 ** Implementation of a scalar function that decodes r-tree nodes to |  | 
|  2759 ** human readable strings. This can be used for debugging and analysis. |  | 
|  2760 ** |  | 
|  2761 ** The scalar function takes two arguments, a blob of data containing |  | 
|  2762 ** an r-tree node, and the number of dimensions the r-tree indexes. |  | 
|  2763 ** For a two-dimensional r-tree structure called "rt", to deserialize |  | 
|  2764 ** all nodes, a statement like: |  | 
|  2765 ** |  | 
|  2766 **   SELECT rtreenode(2, data) FROM rt_node; |  | 
|  2767 ** |  | 
|  2768 ** The human readable string takes the form of a Tcl list with one |  | 
|  2769 ** entry for each cell in the r-tree node. Each entry is itself a |  | 
|  2770 ** list, containing the 8-byte rowid/pageno followed by the  |  | 
|  2771 ** <num-dimension>*2 coordinates. |  | 
|  2772 */ |  | 
|  2773 static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){ |  | 
|  2774   char *zText = 0; |  | 
|  2775   RtreeNode node; |  | 
|  2776   Rtree tree; |  | 
|  2777   int ii; |  | 
|  2778  |  | 
|  2779   memset(&node, 0, sizeof(RtreeNode)); |  | 
|  2780   memset(&tree, 0, sizeof(Rtree)); |  | 
|  2781   tree.nDim = sqlite3_value_int(apArg[0]); |  | 
|  2782   tree.nBytesPerCell = 8 + 8 * tree.nDim; |  | 
|  2783   node.zData = (u8 *)sqlite3_value_blob(apArg[1]); |  | 
|  2784  |  | 
|  2785   for(ii=0; ii<NCELL(&node); ii++){ |  | 
|  2786     char zCell[512]; |  | 
|  2787     int nCell = 0; |  | 
|  2788     RtreeCell cell; |  | 
|  2789     int jj; |  | 
|  2790  |  | 
|  2791     nodeGetCell(&tree, &node, ii, &cell); |  | 
|  2792     sqlite3_snprintf(512-nCell,&zCell[nCell],"%d", cell.iRowid); |  | 
|  2793     nCell = strlen(zCell); |  | 
|  2794     for(jj=0; jj<tree.nDim*2; jj++){ |  | 
|  2795       sqlite3_snprintf(512-nCell,&zCell[nCell]," %f",(double)cell.aCoord[jj].f); |  | 
|  2796       nCell = strlen(zCell); |  | 
|  2797     } |  | 
|  2798  |  | 
|  2799     if( zText ){ |  | 
|  2800       char *zTextNew = sqlite3_mprintf("%s {%s}", zText, zCell); |  | 
|  2801       sqlite3_free(zText); |  | 
|  2802       zText = zTextNew; |  | 
|  2803     }else{ |  | 
|  2804       zText = sqlite3_mprintf("{%s}", zCell); |  | 
|  2805     } |  | 
|  2806   } |  | 
|  2807    |  | 
|  2808   sqlite3_result_text(ctx, zText, -1, sqlite3_free); |  | 
|  2809 } |  | 
|  2810  |  | 
|  2811 static void rtreedepth(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){ |  | 
|  2812   if( sqlite3_value_type(apArg[0])!=SQLITE_BLOB  |  | 
|  2813    || sqlite3_value_bytes(apArg[0])<2 |  | 
|  2814   ){ |  | 
|  2815     sqlite3_result_error(ctx, "Invalid argument to rtreedepth()", -1);  |  | 
|  2816   }else{ |  | 
|  2817     u8 *zBlob = (u8 *)sqlite3_value_blob(apArg[0]); |  | 
|  2818     sqlite3_result_int(ctx, readInt16(zBlob)); |  | 
|  2819   } |  | 
|  2820 } |  | 
|  2821  |  | 
|  2822 /* |  | 
|  2823 ** Register the r-tree module with database handle db. This creates the |  | 
|  2824 ** virtual table module "rtree" and the debugging/analysis scalar  |  | 
|  2825 ** function "rtreenode". |  | 
|  2826 */ |  | 
|  2827 int sqlite3RtreeInit(sqlite3 *db){ |  | 
|  2828   int rc = SQLITE_OK; |  | 
|  2829  |  | 
|  2830   if( rc==SQLITE_OK ){ |  | 
|  2831     int utf8 = SQLITE_UTF8; |  | 
|  2832     rc = sqlite3_create_function(db, "rtreenode", 2, utf8, 0, rtreenode, 0, 0); |  | 
|  2833   } |  | 
|  2834   if( rc==SQLITE_OK ){ |  | 
|  2835     int utf8 = SQLITE_UTF8; |  | 
|  2836     rc = sqlite3_create_function(db, "rtreedepth", 1, utf8, 0,rtreedepth, 0, 0); |  | 
|  2837   } |  | 
|  2838   if( rc==SQLITE_OK ){ |  | 
|  2839     void *c = (void *)RTREE_COORD_REAL32; |  | 
|  2840     rc = sqlite3_create_module_v2(db, "rtree", &rtreeModule, c, 0); |  | 
|  2841   } |  | 
|  2842   if( rc==SQLITE_OK ){ |  | 
|  2843     void *c = (void *)RTREE_COORD_INT32; |  | 
|  2844     rc = sqlite3_create_module_v2(db, "rtree_i32", &rtreeModule, c, 0); |  | 
|  2845   } |  | 
|  2846  |  | 
|  2847   return rc; |  | 
|  2848 } |  | 
|  2849  |  | 
|  2850 #if !SQLITE_CORE |  | 
|  2851 int sqlite3_extension_init( |  | 
|  2852   sqlite3 *db, |  | 
|  2853   char **pzErrMsg, |  | 
|  2854   const sqlite3_api_routines *pApi |  | 
|  2855 ){ |  | 
|  2856   SQLITE_EXTENSION_INIT2(pApi) |  | 
|  2857   return sqlite3RtreeInit(db); |  | 
|  2858 } |  | 
|  2859 #endif |  | 
|  2860  |  | 
|  2861 #endif |  | 
| OLD | NEW |