Annotation of embedaddon/sqlite3/ext/rtree/rtree.c, revision 1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>