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