Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(451)

Side by Side Diff: third_party/sqlite/ext/rtree/rtree.c

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

Powered by Google App Engine
This is Rietveld 408576698