OLD | NEW |
1 /* | 1 /* |
2 ** 2001 September 15 | 2 ** 2001 September 15 |
3 ** | 3 ** |
4 ** The author disclaims copyright to this source code. In place of | 4 ** The author disclaims copyright to this source code. In place of |
5 ** a legal notice, here is a blessing: | 5 ** a legal notice, here is a blessing: |
6 ** | 6 ** |
7 ** May you do good and not evil. | 7 ** May you do good and not evil. |
8 ** May you find forgiveness for yourself and forgive others. | 8 ** May you find forgiveness for yourself and forgive others. |
9 ** May you share freely, never taking more than you give. | 9 ** May you share freely, never taking more than you give. |
10 ** | 10 ** |
11 ************************************************************************* | 11 ************************************************************************* |
12 ** This file contains code for implementations of the r-tree and r*-tree | 12 ** This file contains code for implementations of the r-tree and r*-tree |
13 ** algorithms packaged as an SQLite virtual table module. | 13 ** algorithms packaged as an SQLite virtual table module. |
| 14 */ |
| 15 |
| 16 /* |
| 17 ** Database Format of R-Tree Tables |
| 18 ** -------------------------------- |
14 ** | 19 ** |
15 ** $Id: rtree.c,v 1.14 2009/08/06 18:36:47 danielk1977 Exp $ | 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. |
16 */ | 53 */ |
17 | 54 |
18 #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RTREE) | 55 #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RTREE) |
19 | 56 |
20 /* | 57 /* |
21 ** This file contains an implementation of a couple of different variants | 58 ** 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 | 59 ** 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 | 60 ** 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 | 61 ** delete operations vary. The variants used are selected at compile time |
25 ** by defining the following symbols: | 62 ** by defining the following symbols: |
(...skipping 22 matching lines...) Expand all Loading... |
48 #endif | 85 #endif |
49 #if VARIANT_GUTTMAN_LINEAR_SPLIT | 86 #if VARIANT_GUTTMAN_LINEAR_SPLIT |
50 #define PickNext LinearPickNext | 87 #define PickNext LinearPickNext |
51 #define PickSeeds LinearPickSeeds | 88 #define PickSeeds LinearPickSeeds |
52 #define AssignCells splitNodeGuttman | 89 #define AssignCells splitNodeGuttman |
53 #endif | 90 #endif |
54 #if VARIANT_RSTARTREE_SPLIT | 91 #if VARIANT_RSTARTREE_SPLIT |
55 #define AssignCells splitNodeStartree | 92 #define AssignCells splitNodeStartree |
56 #endif | 93 #endif |
57 | 94 |
| 95 #if !defined(NDEBUG) && !defined(SQLITE_DEBUG) |
| 96 # define NDEBUG 1 |
| 97 #endif |
58 | 98 |
59 #ifndef SQLITE_CORE | 99 #ifndef SQLITE_CORE |
60 #include "sqlite3ext.h" | 100 #include "sqlite3ext.h" |
61 SQLITE_EXTENSION_INIT1 | 101 SQLITE_EXTENSION_INIT1 |
62 #else | 102 #else |
63 #include "sqlite3.h" | 103 #include "sqlite3.h" |
64 #endif | 104 #endif |
65 | 105 |
66 #include <string.h> | 106 #include <string.h> |
67 #include <assert.h> | 107 #include <assert.h> |
68 | 108 |
69 #ifndef SQLITE_AMALGAMATION | 109 #ifndef SQLITE_AMALGAMATION |
| 110 #include "sqlite3rtree.h" |
70 typedef sqlite3_int64 i64; | 111 typedef sqlite3_int64 i64; |
71 typedef unsigned char u8; | 112 typedef unsigned char u8; |
72 typedef unsigned int u32; | 113 typedef unsigned int u32; |
73 #endif | 114 #endif |
74 | 115 |
75 typedef struct Rtree Rtree; | 116 typedef struct Rtree Rtree; |
76 typedef struct RtreeCursor RtreeCursor; | 117 typedef struct RtreeCursor RtreeCursor; |
77 typedef struct RtreeNode RtreeNode; | 118 typedef struct RtreeNode RtreeNode; |
78 typedef struct RtreeCell RtreeCell; | 119 typedef struct RtreeCell RtreeCell; |
79 typedef struct RtreeConstraint RtreeConstraint; | 120 typedef struct RtreeConstraint RtreeConstraint; |
| 121 typedef struct RtreeMatchArg RtreeMatchArg; |
| 122 typedef struct RtreeGeomCallback RtreeGeomCallback; |
80 typedef union RtreeCoord RtreeCoord; | 123 typedef union RtreeCoord RtreeCoord; |
81 | 124 |
82 /* The rtree may have between 1 and RTREE_MAX_DIMENSIONS dimensions. */ | 125 /* The rtree may have between 1 and RTREE_MAX_DIMENSIONS dimensions. */ |
83 #define RTREE_MAX_DIMENSIONS 5 | 126 #define RTREE_MAX_DIMENSIONS 5 |
84 | 127 |
85 /* Size of hash table Rtree.aHash. This hash table is not expected to | 128 /* 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 | 129 ** ever contain very many entries, so a fixed number of buckets is |
87 ** used. | 130 ** used. |
88 */ | 131 */ |
89 #define HASHSIZE 128 | 132 #define HASHSIZE 128 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 ** | 182 ** |
140 ** m = M/3 | 183 ** m = M/3 |
141 ** | 184 ** |
142 ** If an R*-tree "Reinsert" operation is required, the same number of | 185 ** 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. | 186 ** cells are removed from the overfull node and reinserted into the tree. |
144 */ | 187 */ |
145 #define RTREE_MINCELLS(p) ((((p)->iNodeSize-4)/(p)->nBytesPerCell)/3) | 188 #define RTREE_MINCELLS(p) ((((p)->iNodeSize-4)/(p)->nBytesPerCell)/3) |
146 #define RTREE_REINSERT(p) RTREE_MINCELLS(p) | 189 #define RTREE_REINSERT(p) RTREE_MINCELLS(p) |
147 #define RTREE_MAXCELLS 51 | 190 #define RTREE_MAXCELLS 51 |
148 | 191 |
| 192 /* |
| 193 ** The smallest possible node-size is (512-64)==448 bytes. And the largest |
| 194 ** supported cell size is 48 bytes (8 byte rowid + ten 4 byte coordinates). |
| 195 ** Therefore all non-root nodes must contain at least 3 entries. Since |
| 196 ** 2^40 is greater than 2^64, an r-tree structure always has a depth of |
| 197 ** 40 or less. |
| 198 */ |
| 199 #define RTREE_MAX_DEPTH 40 |
| 200 |
149 /* | 201 /* |
150 ** An rtree cursor object. | 202 ** An rtree cursor object. |
151 */ | 203 */ |
152 struct RtreeCursor { | 204 struct RtreeCursor { |
153 sqlite3_vtab_cursor base; | 205 sqlite3_vtab_cursor base; |
154 RtreeNode *pNode; /* Node cursor is currently pointing at */ | 206 RtreeNode *pNode; /* Node cursor is currently pointing at */ |
155 int iCell; /* Index of current cell in pNode */ | 207 int iCell; /* Index of current cell in pNode */ |
156 int iStrategy; /* Copy of idxNum search parameter */ | 208 int iStrategy; /* Copy of idxNum search parameter */ |
157 int nConstraint; /* Number of entries in aConstraint */ | 209 int nConstraint; /* Number of entries in aConstraint */ |
158 RtreeConstraint *aConstraint; /* Search constraints. */ | 210 RtreeConstraint *aConstraint; /* Search constraints. */ |
(...skipping 12 matching lines...) Expand all Loading... |
171 #define DCOORD(coord) ( \ | 223 #define DCOORD(coord) ( \ |
172 (pRtree->eCoordType==RTREE_COORD_REAL32) ? \ | 224 (pRtree->eCoordType==RTREE_COORD_REAL32) ? \ |
173 ((double)coord.f) : \ | 225 ((double)coord.f) : \ |
174 ((double)coord.i) \ | 226 ((double)coord.i) \ |
175 ) | 227 ) |
176 | 228 |
177 /* | 229 /* |
178 ** A search constraint. | 230 ** A search constraint. |
179 */ | 231 */ |
180 struct RtreeConstraint { | 232 struct RtreeConstraint { |
181 int iCoord; /* Index of constrained coordinate */ | 233 int iCoord; /* Index of constrained coordinate */ |
182 int op; /* Constraining operation */ | 234 int op; /* Constraining operation */ |
183 double rValue; /* Constraint value. */ | 235 double rValue; /* Constraint value. */ |
| 236 int (*xGeom)(sqlite3_rtree_geometry *, int, double *, int *); |
| 237 sqlite3_rtree_geometry *pGeom; /* Constraint callback argument for a MATCH */ |
184 }; | 238 }; |
185 | 239 |
186 /* Possible values for RtreeConstraint.op */ | 240 /* Possible values for RtreeConstraint.op */ |
187 #define RTREE_EQ 0x41 | 241 #define RTREE_EQ 0x41 |
188 #define RTREE_LE 0x42 | 242 #define RTREE_LE 0x42 |
189 #define RTREE_LT 0x43 | 243 #define RTREE_LT 0x43 |
190 #define RTREE_GE 0x44 | 244 #define RTREE_GE 0x44 |
191 #define RTREE_GT 0x45 | 245 #define RTREE_GT 0x45 |
| 246 #define RTREE_MATCH 0x46 |
192 | 247 |
193 /* | 248 /* |
194 ** An rtree structure node. | 249 ** 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 */ | 250 */ |
211 struct RtreeNode { | 251 struct RtreeNode { |
212 RtreeNode *pParent; /* Parent node */ | 252 RtreeNode *pParent; /* Parent node */ |
213 i64 iNode; | 253 i64 iNode; |
214 int nRef; | 254 int nRef; |
215 int isDirty; | 255 int isDirty; |
216 u8 *zData; | 256 u8 *zData; |
217 RtreeNode *pNext; /* Next node in this hash chain */ | 257 RtreeNode *pNext; /* Next node in this hash chain */ |
218 }; | 258 }; |
219 #define NCELL(pNode) readInt16(&(pNode)->zData[2]) | 259 #define NCELL(pNode) readInt16(&(pNode)->zData[2]) |
220 | 260 |
221 /* | 261 /* |
222 ** Structure to store a deserialized rtree record. | 262 ** Structure to store a deserialized rtree record. |
223 */ | 263 */ |
224 struct RtreeCell { | 264 struct RtreeCell { |
225 i64 iRowid; | 265 i64 iRowid; |
226 RtreeCoord aCoord[RTREE_MAX_DIMENSIONS*2]; | 266 RtreeCoord aCoord[RTREE_MAX_DIMENSIONS*2]; |
227 }; | 267 }; |
228 | 268 |
| 269 |
| 270 /* |
| 271 ** Value for the first field of every RtreeMatchArg object. The MATCH |
| 272 ** operator tests that the first field of a blob operand matches this |
| 273 ** value to avoid operating on invalid blobs (which could cause a segfault). |
| 274 */ |
| 275 #define RTREE_GEOMETRY_MAGIC 0x891245AB |
| 276 |
| 277 /* |
| 278 ** An instance of this structure must be supplied as a blob argument to |
| 279 ** the right-hand-side of an SQL MATCH operator used to constrain an |
| 280 ** r-tree query. |
| 281 */ |
| 282 struct RtreeMatchArg { |
| 283 u32 magic; /* Always RTREE_GEOMETRY_MAGIC */ |
| 284 int (*xGeom)(sqlite3_rtree_geometry *, int, double *, int *); |
| 285 void *pContext; |
| 286 int nParam; |
| 287 double aParam[1]; |
| 288 }; |
| 289 |
| 290 /* |
| 291 ** When a geometry callback is created (see sqlite3_rtree_geometry_callback), |
| 292 ** a single instance of the following structure is allocated. It is used |
| 293 ** as the context for the user-function created by by s_r_g_c(). The object |
| 294 ** is eventually deleted by the destructor mechanism provided by |
| 295 ** sqlite3_create_function_v2() (which is called by s_r_g_c() to create |
| 296 ** the geometry callback function). |
| 297 */ |
| 298 struct RtreeGeomCallback { |
| 299 int (*xGeom)(sqlite3_rtree_geometry *, int, double *, int *); |
| 300 void *pContext; |
| 301 }; |
| 302 |
229 #ifndef MAX | 303 #ifndef MAX |
230 # define MAX(x,y) ((x) < (y) ? (y) : (x)) | 304 # define MAX(x,y) ((x) < (y) ? (y) : (x)) |
231 #endif | 305 #endif |
232 #ifndef MIN | 306 #ifndef MIN |
233 # define MIN(x,y) ((x) > (y) ? (y) : (x)) | 307 # define MIN(x,y) ((x) > (y) ? (y) : (x)) |
234 #endif | 308 #endif |
235 | 309 |
236 /* | 310 /* |
237 ** Functions to deserialize a 16 bit integer, 32 bit real number and | 311 ** Functions to deserialize a 16 bit integer, 32 bit real number and |
238 ** 64 bit integer. The deserialized value is returned. | 312 ** 64 bit integer. The deserialized value is returned. |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 static void nodeReference(RtreeNode *p){ | 375 static void nodeReference(RtreeNode *p){ |
302 if( p ){ | 376 if( p ){ |
303 p->nRef++; | 377 p->nRef++; |
304 } | 378 } |
305 } | 379 } |
306 | 380 |
307 /* | 381 /* |
308 ** Clear the content of node p (set all bytes to 0x00). | 382 ** Clear the content of node p (set all bytes to 0x00). |
309 */ | 383 */ |
310 static void nodeZero(Rtree *pRtree, RtreeNode *p){ | 384 static void nodeZero(Rtree *pRtree, RtreeNode *p){ |
311 if( p ){ | 385 memset(&p->zData[2], 0, pRtree->iNodeSize-2); |
312 memset(&p->zData[2], 0, pRtree->iNodeSize-2); | 386 p->isDirty = 1; |
313 p->isDirty = 1; | |
314 } | |
315 } | 387 } |
316 | 388 |
317 /* | 389 /* |
318 ** Given a node number iNode, return the corresponding key to use | 390 ** Given a node number iNode, return the corresponding key to use |
319 ** in the Rtree.aHash table. | 391 ** in the Rtree.aHash table. |
320 */ | 392 */ |
321 static int nodeHash(i64 iNode){ | 393 static int nodeHash(i64 iNode){ |
322 return ( | 394 return ( |
323 (iNode>>56) ^ (iNode>>48) ^ (iNode>>40) ^ (iNode>>32) ^ | 395 (iNode>>56) ^ (iNode>>48) ^ (iNode>>40) ^ (iNode>>32) ^ |
324 (iNode>>24) ^ (iNode>>16) ^ (iNode>> 8) ^ (iNode>> 0) | 396 (iNode>>24) ^ (iNode>>16) ^ (iNode>> 8) ^ (iNode>> 0) |
325 ) % HASHSIZE; | 397 ) % HASHSIZE; |
326 } | 398 } |
327 | 399 |
328 /* | 400 /* |
329 ** Search the node hash table for node iNode. If found, return a pointer | 401 ** Search the node hash table for node iNode. If found, return a pointer |
330 ** to it. Otherwise, return 0. | 402 ** to it. Otherwise, return 0. |
331 */ | 403 */ |
332 static RtreeNode *nodeHashLookup(Rtree *pRtree, i64 iNode){ | 404 static RtreeNode *nodeHashLookup(Rtree *pRtree, i64 iNode){ |
333 RtreeNode *p; | 405 RtreeNode *p; |
334 assert( iNode!=0 ); | |
335 for(p=pRtree->aHash[nodeHash(iNode)]; p && p->iNode!=iNode; p=p->pNext); | 406 for(p=pRtree->aHash[nodeHash(iNode)]; p && p->iNode!=iNode; p=p->pNext); |
336 return p; | 407 return p; |
337 } | 408 } |
338 | 409 |
339 /* | 410 /* |
340 ** Add node pNode to the node hash table. | 411 ** Add node pNode to the node hash table. |
341 */ | 412 */ |
342 static void nodeHashInsert(Rtree *pRtree, RtreeNode *pNode){ | 413 static void nodeHashInsert(Rtree *pRtree, RtreeNode *pNode){ |
343 if( pNode ){ | 414 int iHash; |
344 int iHash; | 415 assert( pNode->pNext==0 ); |
345 assert( pNode->pNext==0 ); | 416 iHash = nodeHash(pNode->iNode); |
346 iHash = nodeHash(pNode->iNode); | 417 pNode->pNext = pRtree->aHash[iHash]; |
347 pNode->pNext = pRtree->aHash[iHash]; | 418 pRtree->aHash[iHash] = pNode; |
348 pRtree->aHash[iHash] = pNode; | |
349 } | |
350 } | 419 } |
351 | 420 |
352 /* | 421 /* |
353 ** Remove node pNode from the node hash table. | 422 ** Remove node pNode from the node hash table. |
354 */ | 423 */ |
355 static void nodeHashDelete(Rtree *pRtree, RtreeNode *pNode){ | 424 static void nodeHashDelete(Rtree *pRtree, RtreeNode *pNode){ |
356 RtreeNode **pp; | 425 RtreeNode **pp; |
357 if( pNode->iNode!=0 ){ | 426 if( pNode->iNode!=0 ){ |
358 pp = &pRtree->aHash[nodeHash(pNode->iNode)]; | 427 pp = &pRtree->aHash[nodeHash(pNode->iNode)]; |
359 for( ; (*pp)!=pNode; pp = &(*pp)->pNext){ assert(*pp); } | 428 for( ; (*pp)!=pNode; pp = &(*pp)->pNext){ assert(*pp); } |
360 *pp = pNode->pNext; | 429 *pp = pNode->pNext; |
361 pNode->pNext = 0; | 430 pNode->pNext = 0; |
362 } | 431 } |
363 } | 432 } |
364 | 433 |
365 /* | 434 /* |
366 ** Allocate and return new r-tree node. Initially, (RtreeNode.iNode==0), | 435 ** 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 | 436 ** 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 | 437 ** assigned a node number when nodeWrite() is called to write the |
369 ** node contents out to the database. | 438 ** node contents out to the database. |
370 */ | 439 */ |
371 static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent, int zero){ | 440 static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent){ |
372 RtreeNode *pNode; | 441 RtreeNode *pNode; |
373 pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode) + pRtree->iNodeSize); | 442 pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode) + pRtree->iNodeSize); |
374 if( pNode ){ | 443 if( pNode ){ |
375 memset(pNode, 0, sizeof(RtreeNode) + (zero?pRtree->iNodeSize:0)); | 444 memset(pNode, 0, sizeof(RtreeNode) + pRtree->iNodeSize); |
376 pNode->zData = (u8 *)&pNode[1]; | 445 pNode->zData = (u8 *)&pNode[1]; |
377 pNode->nRef = 1; | 446 pNode->nRef = 1; |
378 pNode->pParent = pParent; | 447 pNode->pParent = pParent; |
379 pNode->isDirty = 1; | 448 pNode->isDirty = 1; |
380 nodeReference(pParent); | 449 nodeReference(pParent); |
381 } | 450 } |
382 return pNode; | 451 return pNode; |
383 } | 452 } |
384 | 453 |
385 /* | 454 /* |
386 ** Obtain a reference to an r-tree node. | 455 ** Obtain a reference to an r-tree node. |
387 */ | 456 */ |
388 static int | 457 static int |
389 nodeAcquire( | 458 nodeAcquire( |
390 Rtree *pRtree, /* R-tree structure */ | 459 Rtree *pRtree, /* R-tree structure */ |
391 i64 iNode, /* Node number to load */ | 460 i64 iNode, /* Node number to load */ |
392 RtreeNode *pParent, /* Either the parent node or NULL */ | 461 RtreeNode *pParent, /* Either the parent node or NULL */ |
393 RtreeNode **ppNode /* OUT: Acquired node */ | 462 RtreeNode **ppNode /* OUT: Acquired node */ |
394 ){ | 463 ){ |
395 int rc; | 464 int rc; |
| 465 int rc2 = SQLITE_OK; |
396 RtreeNode *pNode; | 466 RtreeNode *pNode; |
397 | 467 |
398 /* Check if the requested node is already in the hash table. If so, | 468 /* Check if the requested node is already in the hash table. If so, |
399 ** increase its reference count and return it. | 469 ** increase its reference count and return it. |
400 */ | 470 */ |
401 if( (pNode = nodeHashLookup(pRtree, iNode)) ){ | 471 if( (pNode = nodeHashLookup(pRtree, iNode)) ){ |
402 assert( !pParent || !pNode->pParent || pNode->pParent==pParent ); | 472 assert( !pParent || !pNode->pParent || pNode->pParent==pParent ); |
403 if( pParent && !pNode->pParent ){ | 473 if( pParent && !pNode->pParent ){ |
404 nodeReference(pParent); | 474 nodeReference(pParent); |
405 pNode->pParent = pParent; | 475 pNode->pParent = pParent; |
406 } | 476 } |
407 pNode->nRef++; | 477 pNode->nRef++; |
408 *ppNode = pNode; | 478 *ppNode = pNode; |
409 return SQLITE_OK; | 479 return SQLITE_OK; |
410 } | 480 } |
411 | 481 |
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); | 482 sqlite3_bind_int64(pRtree->pReadNode, 1, iNode); |
425 rc = sqlite3_step(pRtree->pReadNode); | 483 rc = sqlite3_step(pRtree->pReadNode); |
426 if( rc==SQLITE_ROW ){ | 484 if( rc==SQLITE_ROW ){ |
427 const u8 *zBlob = sqlite3_column_blob(pRtree->pReadNode, 0); | 485 const u8 *zBlob = sqlite3_column_blob(pRtree->pReadNode, 0); |
428 memcpy(pNode->zData, zBlob, pRtree->iNodeSize); | 486 if( pRtree->iNodeSize==sqlite3_column_bytes(pRtree->pReadNode, 0) ){ |
429 nodeReference(pParent); | 487 pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode)+pRtree->iNodeSize); |
| 488 if( !pNode ){ |
| 489 rc2 = SQLITE_NOMEM; |
| 490 }else{ |
| 491 pNode->pParent = pParent; |
| 492 pNode->zData = (u8 *)&pNode[1]; |
| 493 pNode->nRef = 1; |
| 494 pNode->iNode = iNode; |
| 495 pNode->isDirty = 0; |
| 496 pNode->pNext = 0; |
| 497 memcpy(pNode->zData, zBlob, pRtree->iNodeSize); |
| 498 nodeReference(pParent); |
| 499 } |
| 500 } |
| 501 } |
| 502 rc = sqlite3_reset(pRtree->pReadNode); |
| 503 if( rc==SQLITE_OK ) rc = rc2; |
| 504 |
| 505 /* If the root node was just loaded, set pRtree->iDepth to the height |
| 506 ** of the r-tree structure. A height of zero means all data is stored on |
| 507 ** the root node. A height of one means the children of the root node |
| 508 ** are the leaves, and so on. If the depth as specified on the root node |
| 509 ** is greater than RTREE_MAX_DEPTH, the r-tree structure must be corrupt. |
| 510 */ |
| 511 if( pNode && iNode==1 ){ |
| 512 pRtree->iDepth = readInt16(pNode->zData); |
| 513 if( pRtree->iDepth>RTREE_MAX_DEPTH ){ |
| 514 rc = SQLITE_CORRUPT; |
| 515 } |
| 516 } |
| 517 |
| 518 /* If no error has occurred so far, check if the "number of entries" |
| 519 ** field on the node is too large. If so, set the return code to |
| 520 ** SQLITE_CORRUPT. |
| 521 */ |
| 522 if( pNode && rc==SQLITE_OK ){ |
| 523 if( NCELL(pNode)>((pRtree->iNodeSize-4)/pRtree->nBytesPerCell) ){ |
| 524 rc = SQLITE_CORRUPT; |
| 525 } |
| 526 } |
| 527 |
| 528 if( rc==SQLITE_OK ){ |
| 529 if( pNode!=0 ){ |
| 530 nodeHashInsert(pRtree, pNode); |
| 531 }else{ |
| 532 rc = SQLITE_CORRUPT; |
| 533 } |
| 534 *ppNode = pNode; |
430 }else{ | 535 }else{ |
431 sqlite3_free(pNode); | 536 sqlite3_free(pNode); |
432 pNode = 0; | 537 *ppNode = 0; |
433 } | 538 } |
434 | 539 |
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; | 540 return rc; |
446 } | 541 } |
447 | 542 |
448 /* | 543 /* |
449 ** Overwrite cell iCell of node pNode with the contents of pCell. | 544 ** Overwrite cell iCell of node pNode with the contents of pCell. |
450 */ | 545 */ |
451 static void nodeOverwriteCell( | 546 static void nodeOverwriteCell( |
452 Rtree *pRtree, | 547 Rtree *pRtree, |
453 RtreeNode *pNode, | 548 RtreeNode *pNode, |
454 RtreeCell *pCell, | 549 RtreeCell *pCell, |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
486 Rtree *pRtree, | 581 Rtree *pRtree, |
487 RtreeNode *pNode, | 582 RtreeNode *pNode, |
488 RtreeCell *pCell | 583 RtreeCell *pCell |
489 ){ | 584 ){ |
490 int nCell; /* Current number of cells in pNode */ | 585 int nCell; /* Current number of cells in pNode */ |
491 int nMaxCell; /* Maximum number of cells for pNode */ | 586 int nMaxCell; /* Maximum number of cells for pNode */ |
492 | 587 |
493 nMaxCell = (pRtree->iNodeSize-4)/pRtree->nBytesPerCell; | 588 nMaxCell = (pRtree->iNodeSize-4)/pRtree->nBytesPerCell; |
494 nCell = NCELL(pNode); | 589 nCell = NCELL(pNode); |
495 | 590 |
496 assert(nCell<=nMaxCell); | 591 assert( nCell<=nMaxCell ); |
497 | |
498 if( nCell<nMaxCell ){ | 592 if( nCell<nMaxCell ){ |
499 nodeOverwriteCell(pRtree, pNode, pCell, nCell); | 593 nodeOverwriteCell(pRtree, pNode, pCell, nCell); |
500 writeInt16(&pNode->zData[2], nCell+1); | 594 writeInt16(&pNode->zData[2], nCell+1); |
501 pNode->isDirty = 1; | 595 pNode->isDirty = 1; |
502 } | 596 } |
503 | 597 |
504 return (nCell==nMaxCell); | 598 return (nCell==nMaxCell); |
505 } | 599 } |
506 | 600 |
507 /* | 601 /* |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
707 if( pCsr ){ | 801 if( pCsr ){ |
708 memset(pCsr, 0, sizeof(RtreeCursor)); | 802 memset(pCsr, 0, sizeof(RtreeCursor)); |
709 pCsr->base.pVtab = pVTab; | 803 pCsr->base.pVtab = pVTab; |
710 rc = SQLITE_OK; | 804 rc = SQLITE_OK; |
711 } | 805 } |
712 *ppCursor = (sqlite3_vtab_cursor *)pCsr; | 806 *ppCursor = (sqlite3_vtab_cursor *)pCsr; |
713 | 807 |
714 return rc; | 808 return rc; |
715 } | 809 } |
716 | 810 |
| 811 |
| 812 /* |
| 813 ** Free the RtreeCursor.aConstraint[] array and its contents. |
| 814 */ |
| 815 static void freeCursorConstraints(RtreeCursor *pCsr){ |
| 816 if( pCsr->aConstraint ){ |
| 817 int i; /* Used to iterate through constraint array */ |
| 818 for(i=0; i<pCsr->nConstraint; i++){ |
| 819 sqlite3_rtree_geometry *pGeom = pCsr->aConstraint[i].pGeom; |
| 820 if( pGeom ){ |
| 821 if( pGeom->xDelUser ) pGeom->xDelUser(pGeom->pUser); |
| 822 sqlite3_free(pGeom); |
| 823 } |
| 824 } |
| 825 sqlite3_free(pCsr->aConstraint); |
| 826 pCsr->aConstraint = 0; |
| 827 } |
| 828 } |
| 829 |
717 /* | 830 /* |
718 ** Rtree virtual table module xClose method. | 831 ** Rtree virtual table module xClose method. |
719 */ | 832 */ |
720 static int rtreeClose(sqlite3_vtab_cursor *cur){ | 833 static int rtreeClose(sqlite3_vtab_cursor *cur){ |
721 Rtree *pRtree = (Rtree *)(cur->pVtab); | 834 Rtree *pRtree = (Rtree *)(cur->pVtab); |
722 int rc; | 835 int rc; |
723 RtreeCursor *pCsr = (RtreeCursor *)cur; | 836 RtreeCursor *pCsr = (RtreeCursor *)cur; |
724 sqlite3_free(pCsr->aConstraint); | 837 freeCursorConstraints(pCsr); |
725 rc = nodeRelease(pRtree, pCsr->pNode); | 838 rc = nodeRelease(pRtree, pCsr->pNode); |
726 sqlite3_free(pCsr); | 839 sqlite3_free(pCsr); |
727 return rc; | 840 return rc; |
728 } | 841 } |
729 | 842 |
730 /* | 843 /* |
731 ** Rtree virtual table module xEof method. | 844 ** Rtree virtual table module xEof method. |
732 ** | 845 ** |
733 ** Return non-zero if the cursor does not currently point to a valid | 846 ** 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. | 847 ** record (i.e if the scan has finished), or zero otherwise. |
735 */ | 848 */ |
736 static int rtreeEof(sqlite3_vtab_cursor *cur){ | 849 static int rtreeEof(sqlite3_vtab_cursor *cur){ |
737 RtreeCursor *pCsr = (RtreeCursor *)cur; | 850 RtreeCursor *pCsr = (RtreeCursor *)cur; |
738 return (pCsr->pNode==0); | 851 return (pCsr->pNode==0); |
739 } | 852 } |
740 | 853 |
| 854 /* |
| 855 ** The r-tree constraint passed as the second argument to this function is |
| 856 ** guaranteed to be a MATCH constraint. |
| 857 */ |
| 858 static int testRtreeGeom( |
| 859 Rtree *pRtree, /* R-Tree object */ |
| 860 RtreeConstraint *pConstraint, /* MATCH constraint to test */ |
| 861 RtreeCell *pCell, /* Cell to test */ |
| 862 int *pbRes /* OUT: Test result */ |
| 863 ){ |
| 864 int i; |
| 865 double aCoord[RTREE_MAX_DIMENSIONS*2]; |
| 866 int nCoord = pRtree->nDim*2; |
| 867 |
| 868 assert( pConstraint->op==RTREE_MATCH ); |
| 869 assert( pConstraint->pGeom ); |
| 870 |
| 871 for(i=0; i<nCoord; i++){ |
| 872 aCoord[i] = DCOORD(pCell->aCoord[i]); |
| 873 } |
| 874 return pConstraint->xGeom(pConstraint->pGeom, nCoord, aCoord, pbRes); |
| 875 } |
| 876 |
741 /* | 877 /* |
742 ** Cursor pCursor currently points to a cell in a non-leaf page. | 878 ** 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 | 879 ** Set *pbEof to true if the sub-tree headed by the cell is filtered |
744 ** (excluded) by the constraints in the pCursor->aConstraint[] | 880 ** (excluded) by the constraints in the pCursor->aConstraint[] |
745 ** array, or false otherwise. | 881 ** array, or false otherwise. |
| 882 ** |
| 883 ** Return SQLITE_OK if successful or an SQLite error code if an error |
| 884 ** occurs within a geometry callback. |
746 */ | 885 */ |
747 static int testRtreeCell(Rtree *pRtree, RtreeCursor *pCursor){ | 886 static int testRtreeCell(Rtree *pRtree, RtreeCursor *pCursor, int *pbEof){ |
748 RtreeCell cell; | 887 RtreeCell cell; |
749 int ii; | 888 int ii; |
750 int bRes = 0; | 889 int bRes = 0; |
751 | 890 |
752 nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell); | 891 nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell); |
753 for(ii=0; bRes==0 && ii<pCursor->nConstraint; ii++){ | 892 for(ii=0; bRes==0 && ii<pCursor->nConstraint; ii++){ |
754 RtreeConstraint *p = &pCursor->aConstraint[ii]; | 893 RtreeConstraint *p = &pCursor->aConstraint[ii]; |
755 double cell_min = DCOORD(cell.aCoord[(p->iCoord>>1)*2]); | 894 double cell_min = DCOORD(cell.aCoord[(p->iCoord>>1)*2]); |
756 double cell_max = DCOORD(cell.aCoord[(p->iCoord>>1)*2+1]); | 895 double cell_max = DCOORD(cell.aCoord[(p->iCoord>>1)*2+1]); |
757 | 896 |
758 assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE | 897 assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE |
759 || p->op==RTREE_GT || p->op==RTREE_EQ | 898 || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_MATCH |
760 ); | 899 ); |
761 | 900 |
762 switch( p->op ){ | 901 switch( p->op ){ |
763 case RTREE_LE: case RTREE_LT: bRes = p->rValue<cell_min; break; | 902 case RTREE_LE: case RTREE_LT: |
764 case RTREE_GE: case RTREE_GT: bRes = p->rValue>cell_max; break; | 903 bRes = p->rValue<cell_min; |
765 case RTREE_EQ: | 904 break; |
| 905 |
| 906 case RTREE_GE: case RTREE_GT: |
| 907 bRes = p->rValue>cell_max; |
| 908 break; |
| 909 |
| 910 case RTREE_EQ: |
766 bRes = (p->rValue>cell_max || p->rValue<cell_min); | 911 bRes = (p->rValue>cell_max || p->rValue<cell_min); |
767 break; | 912 break; |
| 913 |
| 914 default: { |
| 915 int rc; |
| 916 assert( p->op==RTREE_MATCH ); |
| 917 rc = testRtreeGeom(pRtree, p, &cell, &bRes); |
| 918 if( rc!=SQLITE_OK ){ |
| 919 return rc; |
| 920 } |
| 921 bRes = !bRes; |
| 922 break; |
| 923 } |
768 } | 924 } |
769 } | 925 } |
770 | 926 |
771 return bRes; | 927 *pbEof = bRes; |
| 928 return SQLITE_OK; |
772 } | 929 } |
773 | 930 |
774 /* | 931 /* |
775 ** Return true if the cell that cursor pCursor currently points to | 932 ** Test if the cell that cursor pCursor currently points to |
776 ** would be filtered (excluded) by the constraints in the | 933 ** would be filtered (excluded) by the constraints in the |
777 ** pCursor->aConstraint[] array, or false otherwise. | 934 ** pCursor->aConstraint[] array. If so, set *pbEof to true before |
| 935 ** returning. If the cell is not filtered (excluded) by the constraints, |
| 936 ** set pbEof to zero. |
| 937 ** |
| 938 ** Return SQLITE_OK if successful or an SQLite error code if an error |
| 939 ** occurs within a geometry callback. |
778 ** | 940 ** |
779 ** This function assumes that the cell is part of a leaf node. | 941 ** This function assumes that the cell is part of a leaf node. |
780 */ | 942 */ |
781 static int testRtreeEntry(Rtree *pRtree, RtreeCursor *pCursor){ | 943 static int testRtreeEntry(Rtree *pRtree, RtreeCursor *pCursor, int *pbEof){ |
782 RtreeCell cell; | 944 RtreeCell cell; |
783 int ii; | 945 int ii; |
| 946 *pbEof = 0; |
784 | 947 |
785 nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell); | 948 nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell); |
786 for(ii=0; ii<pCursor->nConstraint; ii++){ | 949 for(ii=0; ii<pCursor->nConstraint; ii++){ |
787 RtreeConstraint *p = &pCursor->aConstraint[ii]; | 950 RtreeConstraint *p = &pCursor->aConstraint[ii]; |
788 double coord = DCOORD(cell.aCoord[p->iCoord]); | 951 double coord = DCOORD(cell.aCoord[p->iCoord]); |
789 int res; | 952 int res; |
790 assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE | 953 assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE |
791 || p->op==RTREE_GT || p->op==RTREE_EQ | 954 || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_MATCH |
792 ); | 955 ); |
793 switch( p->op ){ | 956 switch( p->op ){ |
794 case RTREE_LE: res = (coord<=p->rValue); break; | 957 case RTREE_LE: res = (coord<=p->rValue); break; |
795 case RTREE_LT: res = (coord<p->rValue); break; | 958 case RTREE_LT: res = (coord<p->rValue); break; |
796 case RTREE_GE: res = (coord>=p->rValue); break; | 959 case RTREE_GE: res = (coord>=p->rValue); break; |
797 case RTREE_GT: res = (coord>p->rValue); break; | 960 case RTREE_GT: res = (coord>p->rValue); break; |
798 case RTREE_EQ: res = (coord==p->rValue); break; | 961 case RTREE_EQ: res = (coord==p->rValue); break; |
| 962 default: { |
| 963 int rc; |
| 964 assert( p->op==RTREE_MATCH ); |
| 965 rc = testRtreeGeom(pRtree, p, &cell, &res); |
| 966 if( rc!=SQLITE_OK ){ |
| 967 return rc; |
| 968 } |
| 969 break; |
| 970 } |
799 } | 971 } |
800 | 972 |
801 if( !res ) return 1; | 973 if( !res ){ |
| 974 *pbEof = 1; |
| 975 return SQLITE_OK; |
| 976 } |
802 } | 977 } |
803 | 978 |
804 return 0; | 979 return SQLITE_OK; |
805 } | 980 } |
806 | 981 |
807 /* | 982 /* |
808 ** Cursor pCursor currently points at a node that heads a sub-tree of | 983 ** 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 | 984 ** 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 | 985 ** to point to the left-most cell of the sub-tree that matches the |
811 ** configured constraints. | 986 ** configured constraints. |
812 */ | 987 */ |
813 static int descendToCell( | 988 static int descendToCell( |
814 Rtree *pRtree, | 989 Rtree *pRtree, |
815 RtreeCursor *pCursor, | 990 RtreeCursor *pCursor, |
816 int iHeight, | 991 int iHeight, |
817 int *pEof /* OUT: Set to true if cannot descend */ | 992 int *pEof /* OUT: Set to true if cannot descend */ |
818 ){ | 993 ){ |
819 int isEof; | 994 int isEof; |
820 int rc; | 995 int rc; |
821 int ii; | 996 int ii; |
822 RtreeNode *pChild; | 997 RtreeNode *pChild; |
823 sqlite3_int64 iRowid; | 998 sqlite3_int64 iRowid; |
824 | 999 |
825 RtreeNode *pSavedNode = pCursor->pNode; | 1000 RtreeNode *pSavedNode = pCursor->pNode; |
826 int iSavedCell = pCursor->iCell; | 1001 int iSavedCell = pCursor->iCell; |
827 | 1002 |
828 assert( iHeight>=0 ); | 1003 assert( iHeight>=0 ); |
829 | 1004 |
830 if( iHeight==0 ){ | 1005 if( iHeight==0 ){ |
831 isEof = testRtreeEntry(pRtree, pCursor); | 1006 rc = testRtreeEntry(pRtree, pCursor, &isEof); |
832 }else{ | 1007 }else{ |
833 isEof = testRtreeCell(pRtree, pCursor); | 1008 rc = testRtreeCell(pRtree, pCursor, &isEof); |
834 } | 1009 } |
835 if( isEof || iHeight==0 ){ | 1010 if( rc!=SQLITE_OK || isEof || iHeight==0 ){ |
836 *pEof = isEof; | 1011 *pEof = isEof; |
837 return SQLITE_OK; | 1012 return rc; |
838 } | 1013 } |
839 | 1014 |
840 iRowid = nodeGetRowid(pRtree, pCursor->pNode, pCursor->iCell); | 1015 iRowid = nodeGetRowid(pRtree, pCursor->pNode, pCursor->iCell); |
841 rc = nodeAcquire(pRtree, iRowid, pCursor->pNode, &pChild); | 1016 rc = nodeAcquire(pRtree, iRowid, pCursor->pNode, &pChild); |
842 if( rc!=SQLITE_OK ){ | 1017 if( rc!=SQLITE_OK ){ |
843 return rc; | 1018 return rc; |
844 } | 1019 } |
845 | 1020 |
846 nodeRelease(pRtree, pCursor->pNode); | 1021 nodeRelease(pRtree, pCursor->pNode); |
847 pCursor->pNode = pChild; | 1022 pCursor->pNode = pChild; |
(...skipping 15 matching lines...) Expand all Loading... |
863 } | 1038 } |
864 | 1039 |
865 *pEof = isEof; | 1040 *pEof = isEof; |
866 return SQLITE_OK; | 1041 return SQLITE_OK; |
867 } | 1042 } |
868 | 1043 |
869 /* | 1044 /* |
870 ** One of the cells in node pNode is guaranteed to have a 64-bit | 1045 ** 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. | 1046 ** integer value equal to iRowid. Return the index of this cell. |
872 */ | 1047 */ |
873 static int nodeRowidIndex(Rtree *pRtree, RtreeNode *pNode, i64 iRowid){ | 1048 static int nodeRowidIndex( |
| 1049 Rtree *pRtree, |
| 1050 RtreeNode *pNode, |
| 1051 i64 iRowid, |
| 1052 int *piIndex |
| 1053 ){ |
874 int ii; | 1054 int ii; |
875 for(ii=0; nodeGetRowid(pRtree, pNode, ii)!=iRowid; ii++){ | 1055 int nCell = NCELL(pNode); |
876 assert( ii<(NCELL(pNode)-1) ); | 1056 for(ii=0; ii<nCell; ii++){ |
| 1057 if( nodeGetRowid(pRtree, pNode, ii)==iRowid ){ |
| 1058 *piIndex = ii; |
| 1059 return SQLITE_OK; |
| 1060 } |
877 } | 1061 } |
878 return ii; | 1062 return SQLITE_CORRUPT; |
879 } | 1063 } |
880 | 1064 |
881 /* | 1065 /* |
882 ** Return the index of the cell containing a pointer to node pNode | 1066 ** Return the index of the cell containing a pointer to node pNode |
883 ** in its parent. If pNode is the root node, return -1. | 1067 ** in its parent. If pNode is the root node, return -1. |
884 */ | 1068 */ |
885 static int nodeParentIndex(Rtree *pRtree, RtreeNode *pNode){ | 1069 static int nodeParentIndex(Rtree *pRtree, RtreeNode *pNode, int *piIndex){ |
886 RtreeNode *pParent = pNode->pParent; | 1070 RtreeNode *pParent = pNode->pParent; |
887 if( pParent ){ | 1071 if( pParent ){ |
888 return nodeRowidIndex(pRtree, pParent, pNode->iNode); | 1072 return nodeRowidIndex(pRtree, pParent, pNode->iNode, piIndex); |
889 } | 1073 } |
890 return -1; | 1074 *piIndex = -1; |
| 1075 return SQLITE_OK; |
891 } | 1076 } |
892 | 1077 |
893 /* | 1078 /* |
894 ** Rtree virtual table module xNext method. | 1079 ** Rtree virtual table module xNext method. |
895 */ | 1080 */ |
896 static int rtreeNext(sqlite3_vtab_cursor *pVtabCursor){ | 1081 static int rtreeNext(sqlite3_vtab_cursor *pVtabCursor){ |
897 Rtree *pRtree = (Rtree *)(pVtabCursor->pVtab); | 1082 Rtree *pRtree = (Rtree *)(pVtabCursor->pVtab); |
898 RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; | 1083 RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; |
899 int rc = SQLITE_OK; | 1084 int rc = SQLITE_OK; |
900 | 1085 |
| 1086 /* RtreeCursor.pNode must not be NULL. If is is NULL, then this cursor is |
| 1087 ** already at EOF. It is against the rules to call the xNext() method of |
| 1088 ** a cursor that has already reached EOF. |
| 1089 */ |
| 1090 assert( pCsr->pNode ); |
| 1091 |
901 if( pCsr->iStrategy==1 ){ | 1092 if( pCsr->iStrategy==1 ){ |
902 /* This "scan" is a direct lookup by rowid. There is no next entry. */ | 1093 /* This "scan" is a direct lookup by rowid. There is no next entry. */ |
903 nodeRelease(pRtree, pCsr->pNode); | 1094 nodeRelease(pRtree, pCsr->pNode); |
904 pCsr->pNode = 0; | 1095 pCsr->pNode = 0; |
905 } | 1096 }else{ |
906 | |
907 else if( pCsr->pNode ){ | |
908 /* Move to the next entry that matches the configured constraints. */ | 1097 /* Move to the next entry that matches the configured constraints. */ |
909 int iHeight = 0; | 1098 int iHeight = 0; |
910 while( pCsr->pNode ){ | 1099 while( pCsr->pNode ){ |
911 RtreeNode *pNode = pCsr->pNode; | 1100 RtreeNode *pNode = pCsr->pNode; |
912 int nCell = NCELL(pNode); | 1101 int nCell = NCELL(pNode); |
913 for(pCsr->iCell++; pCsr->iCell<nCell; pCsr->iCell++){ | 1102 for(pCsr->iCell++; pCsr->iCell<nCell; pCsr->iCell++){ |
914 int isEof; | 1103 int isEof; |
915 rc = descendToCell(pRtree, pCsr, iHeight, &isEof); | 1104 rc = descendToCell(pRtree, pCsr, iHeight, &isEof); |
916 if( rc!=SQLITE_OK || !isEof ){ | 1105 if( rc!=SQLITE_OK || !isEof ){ |
917 return rc; | 1106 return rc; |
918 } | 1107 } |
919 } | 1108 } |
920 pCsr->pNode = pNode->pParent; | 1109 pCsr->pNode = pNode->pParent; |
921 pCsr->iCell = nodeParentIndex(pRtree, pNode); | 1110 rc = nodeParentIndex(pRtree, pNode, &pCsr->iCell); |
| 1111 if( rc!=SQLITE_OK ){ |
| 1112 return rc; |
| 1113 } |
922 nodeReference(pCsr->pNode); | 1114 nodeReference(pCsr->pNode); |
923 nodeRelease(pRtree, pNode); | 1115 nodeRelease(pRtree, pNode); |
924 iHeight++; | 1116 iHeight++; |
925 } | 1117 } |
926 } | 1118 } |
927 | 1119 |
928 return rc; | 1120 return rc; |
929 } | 1121 } |
930 | 1122 |
931 /* | 1123 /* |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
979 if( sqlite3_step(pRtree->pReadRowid)==SQLITE_ROW ){ | 1171 if( sqlite3_step(pRtree->pReadRowid)==SQLITE_ROW ){ |
980 i64 iNode = sqlite3_column_int64(pRtree->pReadRowid, 0); | 1172 i64 iNode = sqlite3_column_int64(pRtree->pReadRowid, 0); |
981 rc = nodeAcquire(pRtree, iNode, 0, ppLeaf); | 1173 rc = nodeAcquire(pRtree, iNode, 0, ppLeaf); |
982 sqlite3_reset(pRtree->pReadRowid); | 1174 sqlite3_reset(pRtree->pReadRowid); |
983 }else{ | 1175 }else{ |
984 rc = sqlite3_reset(pRtree->pReadRowid); | 1176 rc = sqlite3_reset(pRtree->pReadRowid); |
985 } | 1177 } |
986 return rc; | 1178 return rc; |
987 } | 1179 } |
988 | 1180 |
| 1181 /* |
| 1182 ** This function is called to configure the RtreeConstraint object passed |
| 1183 ** as the second argument for a MATCH constraint. The value passed as the |
| 1184 ** first argument to this function is the right-hand operand to the MATCH |
| 1185 ** operator. |
| 1186 */ |
| 1187 static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){ |
| 1188 RtreeMatchArg *p; |
| 1189 sqlite3_rtree_geometry *pGeom; |
| 1190 int nBlob; |
| 1191 |
| 1192 /* Check that value is actually a blob. */ |
| 1193 if( !sqlite3_value_type(pValue)==SQLITE_BLOB ) return SQLITE_ERROR; |
| 1194 |
| 1195 /* Check that the blob is roughly the right size. */ |
| 1196 nBlob = sqlite3_value_bytes(pValue); |
| 1197 if( nBlob<sizeof(RtreeMatchArg) |
| 1198 || ((nBlob-sizeof(RtreeMatchArg))%sizeof(double))!=0 |
| 1199 ){ |
| 1200 return SQLITE_ERROR; |
| 1201 } |
| 1202 |
| 1203 pGeom = (sqlite3_rtree_geometry *)sqlite3_malloc( |
| 1204 sizeof(sqlite3_rtree_geometry) + nBlob |
| 1205 ); |
| 1206 if( !pGeom ) return SQLITE_NOMEM; |
| 1207 memset(pGeom, 0, sizeof(sqlite3_rtree_geometry)); |
| 1208 p = (RtreeMatchArg *)&pGeom[1]; |
| 1209 |
| 1210 memcpy(p, sqlite3_value_blob(pValue), nBlob); |
| 1211 if( p->magic!=RTREE_GEOMETRY_MAGIC |
| 1212 || nBlob!=(sizeof(RtreeMatchArg) + (p->nParam-1)*sizeof(double)) |
| 1213 ){ |
| 1214 sqlite3_free(pGeom); |
| 1215 return SQLITE_ERROR; |
| 1216 } |
| 1217 |
| 1218 pGeom->pContext = p->pContext; |
| 1219 pGeom->nParam = p->nParam; |
| 1220 pGeom->aParam = p->aParam; |
| 1221 |
| 1222 pCons->xGeom = p->xGeom; |
| 1223 pCons->pGeom = pGeom; |
| 1224 return SQLITE_OK; |
| 1225 } |
989 | 1226 |
990 /* | 1227 /* |
991 ** Rtree virtual table module xFilter method. | 1228 ** Rtree virtual table module xFilter method. |
992 */ | 1229 */ |
993 static int rtreeFilter( | 1230 static int rtreeFilter( |
994 sqlite3_vtab_cursor *pVtabCursor, | 1231 sqlite3_vtab_cursor *pVtabCursor, |
995 int idxNum, const char *idxStr, | 1232 int idxNum, const char *idxStr, |
996 int argc, sqlite3_value **argv | 1233 int argc, sqlite3_value **argv |
997 ){ | 1234 ){ |
998 Rtree *pRtree = (Rtree *)pVtabCursor->pVtab; | 1235 Rtree *pRtree = (Rtree *)pVtabCursor->pVtab; |
999 RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; | 1236 RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; |
1000 | 1237 |
1001 RtreeNode *pRoot = 0; | 1238 RtreeNode *pRoot = 0; |
1002 int ii; | 1239 int ii; |
1003 int rc = SQLITE_OK; | 1240 int rc = SQLITE_OK; |
1004 | 1241 |
1005 rtreeReference(pRtree); | 1242 rtreeReference(pRtree); |
1006 | 1243 |
1007 sqlite3_free(pCsr->aConstraint); | 1244 freeCursorConstraints(pCsr); |
1008 pCsr->aConstraint = 0; | |
1009 pCsr->iStrategy = idxNum; | 1245 pCsr->iStrategy = idxNum; |
1010 | 1246 |
1011 if( idxNum==1 ){ | 1247 if( idxNum==1 ){ |
1012 /* Special case - lookup by rowid. */ | 1248 /* Special case - lookup by rowid. */ |
1013 RtreeNode *pLeaf; /* Leaf on which the required cell resides */ | 1249 RtreeNode *pLeaf; /* Leaf on which the required cell resides */ |
1014 i64 iRowid = sqlite3_value_int64(argv[0]); | 1250 i64 iRowid = sqlite3_value_int64(argv[0]); |
1015 rc = findLeafNode(pRtree, iRowid, &pLeaf); | 1251 rc = findLeafNode(pRtree, iRowid, &pLeaf); |
1016 pCsr->pNode = pLeaf; | 1252 pCsr->pNode = pLeaf; |
1017 if( pLeaf && rc==SQLITE_OK ){ | 1253 if( pLeaf ){ |
1018 pCsr->iCell = nodeRowidIndex(pRtree, pLeaf, iRowid); | 1254 assert( rc==SQLITE_OK ); |
| 1255 rc = nodeRowidIndex(pRtree, pLeaf, iRowid, &pCsr->iCell); |
1019 } | 1256 } |
1020 }else{ | 1257 }else{ |
1021 /* Normal case - r-tree scan. Set up the RtreeCursor.aConstraint array | 1258 /* Normal case - r-tree scan. Set up the RtreeCursor.aConstraint array |
1022 ** with the configured constraints. | 1259 ** with the configured constraints. |
1023 */ | 1260 */ |
1024 if( argc>0 ){ | 1261 if( argc>0 ){ |
1025 pCsr->aConstraint = sqlite3_malloc(sizeof(RtreeConstraint)*argc); | 1262 pCsr->aConstraint = sqlite3_malloc(sizeof(RtreeConstraint)*argc); |
1026 pCsr->nConstraint = argc; | 1263 pCsr->nConstraint = argc; |
1027 if( !pCsr->aConstraint ){ | 1264 if( !pCsr->aConstraint ){ |
1028 rc = SQLITE_NOMEM; | 1265 rc = SQLITE_NOMEM; |
1029 }else{ | 1266 }else{ |
| 1267 memset(pCsr->aConstraint, 0, sizeof(RtreeConstraint)*argc); |
1030 assert( (idxStr==0 && argc==0) || strlen(idxStr)==argc*2 ); | 1268 assert( (idxStr==0 && argc==0) || strlen(idxStr)==argc*2 ); |
1031 for(ii=0; ii<argc; ii++){ | 1269 for(ii=0; ii<argc; ii++){ |
1032 RtreeConstraint *p = &pCsr->aConstraint[ii]; | 1270 RtreeConstraint *p = &pCsr->aConstraint[ii]; |
1033 p->op = idxStr[ii*2]; | 1271 p->op = idxStr[ii*2]; |
1034 p->iCoord = idxStr[ii*2+1]-'a'; | 1272 p->iCoord = idxStr[ii*2+1]-'a'; |
1035 p->rValue = sqlite3_value_double(argv[ii]); | 1273 if( p->op==RTREE_MATCH ){ |
| 1274 /* A MATCH operator. The right-hand-side must be a blob that |
| 1275 ** can be cast into an RtreeMatchArg object. One created using |
| 1276 ** an sqlite3_rtree_geometry_callback() SQL user function. |
| 1277 */ |
| 1278 rc = deserializeGeometry(argv[ii], p); |
| 1279 if( rc!=SQLITE_OK ){ |
| 1280 break; |
| 1281 } |
| 1282 }else{ |
| 1283 p->rValue = sqlite3_value_double(argv[ii]); |
| 1284 } |
1036 } | 1285 } |
1037 } | 1286 } |
1038 } | 1287 } |
1039 | 1288 |
1040 if( rc==SQLITE_OK ){ | 1289 if( rc==SQLITE_OK ){ |
1041 pCsr->pNode = 0; | 1290 pCsr->pNode = 0; |
1042 rc = nodeAcquire(pRtree, 1, 0, &pRoot); | 1291 rc = nodeAcquire(pRtree, 1, 0, &pRoot); |
1043 } | 1292 } |
1044 if( rc==SQLITE_OK ){ | 1293 if( rc==SQLITE_OK ){ |
1045 int isEof = 1; | 1294 int isEof = 1; |
(...skipping 20 matching lines...) Expand all Loading... |
1066 } | 1315 } |
1067 | 1316 |
1068 /* | 1317 /* |
1069 ** Rtree virtual table module xBestIndex method. There are three | 1318 ** Rtree virtual table module xBestIndex method. There are three |
1070 ** table scan strategies to choose from (in order from most to | 1319 ** table scan strategies to choose from (in order from most to |
1071 ** least desirable): | 1320 ** least desirable): |
1072 ** | 1321 ** |
1073 ** idxNum idxStr Strategy | 1322 ** idxNum idxStr Strategy |
1074 ** ------------------------------------------------ | 1323 ** ------------------------------------------------ |
1075 ** 1 Unused Direct lookup by rowid. | 1324 ** 1 Unused Direct lookup by rowid. |
1076 ** 2 See below R-tree query. | 1325 ** 2 See below R-tree query or full-table scan. |
1077 ** 3 Unused Full table scan. | |
1078 ** ------------------------------------------------ | 1326 ** ------------------------------------------------ |
1079 ** | 1327 ** |
1080 ** If strategy 1 or 3 is used, then idxStr is not meaningful. If strategy | 1328 ** If strategy 1 is used, then idxStr is not meaningful. If strategy |
1081 ** 2 is used, idxStr is formatted to contain 2 bytes for each | 1329 ** 2 is used, idxStr is formatted to contain 2 bytes for each |
1082 ** constraint used. The first two bytes of idxStr correspond to | 1330 ** constraint used. The first two bytes of idxStr correspond to |
1083 ** the constraint in sqlite3_index_info.aConstraintUsage[] with | 1331 ** the constraint in sqlite3_index_info.aConstraintUsage[] with |
1084 ** (argvIndex==1) etc. | 1332 ** (argvIndex==1) etc. |
1085 ** | 1333 ** |
1086 ** The first of each pair of bytes in idxStr identifies the constraint | 1334 ** The first of each pair of bytes in idxStr identifies the constraint |
1087 ** operator as follows: | 1335 ** operator as follows: |
1088 ** | 1336 ** |
1089 ** Operator Byte Value | 1337 ** Operator Byte Value |
1090 ** ---------------------- | 1338 ** ---------------------- |
1091 ** = 0x41 ('A') | 1339 ** = 0x41 ('A') |
1092 ** <= 0x42 ('B') | 1340 ** <= 0x42 ('B') |
1093 ** < 0x43 ('C') | 1341 ** < 0x43 ('C') |
1094 ** >= 0x44 ('D') | 1342 ** >= 0x44 ('D') |
1095 ** > 0x45 ('E') | 1343 ** > 0x45 ('E') |
| 1344 ** MATCH 0x46 ('F') |
1096 ** ---------------------- | 1345 ** ---------------------- |
1097 ** | 1346 ** |
1098 ** The second of each pair of bytes identifies the coordinate column | 1347 ** The second of each pair of bytes identifies the coordinate column |
1099 ** to which the constraint applies. The leftmost coordinate column | 1348 ** to which the constraint applies. The leftmost coordinate column |
1100 ** is 'a', the second from the left 'b' etc. | 1349 ** is 'a', the second from the left 'b' etc. |
1101 */ | 1350 */ |
1102 static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ | 1351 static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ |
1103 int rc = SQLITE_OK; | 1352 int rc = SQLITE_OK; |
1104 int ii, cCol; | 1353 int ii, cCol; |
1105 | 1354 |
(...skipping 18 matching lines...) Expand all Loading... |
1124 | 1373 |
1125 /* This strategy involves a two rowid lookups on an B-Tree structures | 1374 /* 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 | 1375 ** 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 | 1376 ** considered almost as quick as a direct rowid lookup (for which |
1128 ** sqlite uses an internal cost of 0.0). | 1377 ** sqlite uses an internal cost of 0.0). |
1129 */ | 1378 */ |
1130 pIdxInfo->estimatedCost = 10.0; | 1379 pIdxInfo->estimatedCost = 10.0; |
1131 return SQLITE_OK; | 1380 return SQLITE_OK; |
1132 } | 1381 } |
1133 | 1382 |
1134 if( p->usable && p->iColumn>0 ){ | 1383 if( p->usable && (p->iColumn>0 || p->op==SQLITE_INDEX_CONSTRAINT_MATCH) ){ |
| 1384 int j, opmsk; |
| 1385 static const unsigned char compatible[] = { 0, 0, 1, 1, 2, 2 }; |
1135 u8 op = 0; | 1386 u8 op = 0; |
1136 switch( p->op ){ | 1387 switch( p->op ){ |
1137 case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; break; | 1388 case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; break; |
1138 case SQLITE_INDEX_CONSTRAINT_GT: op = RTREE_GT; break; | 1389 case SQLITE_INDEX_CONSTRAINT_GT: op = RTREE_GT; break; |
1139 case SQLITE_INDEX_CONSTRAINT_LE: op = RTREE_LE; break; | 1390 case SQLITE_INDEX_CONSTRAINT_LE: op = RTREE_LE; break; |
1140 case SQLITE_INDEX_CONSTRAINT_LT: op = RTREE_LT; break; | 1391 case SQLITE_INDEX_CONSTRAINT_LT: op = RTREE_LT; break; |
1141 case SQLITE_INDEX_CONSTRAINT_GE: op = RTREE_GE; break; | 1392 case SQLITE_INDEX_CONSTRAINT_GE: op = RTREE_GE; break; |
| 1393 default: |
| 1394 assert( p->op==SQLITE_INDEX_CONSTRAINT_MATCH ); |
| 1395 op = RTREE_MATCH; |
| 1396 break; |
1142 } | 1397 } |
1143 if( op ){ | 1398 assert( op!=0 ); |
1144 /* Make sure this particular constraint has not been used before. | 1399 |
1145 ** If it has been used before, ignore it. | 1400 /* Make sure this particular constraint has not been used before. |
1146 ** | 1401 ** If it has been used before, ignore it. |
1147 ** A <= or < can be used if there is a prior >= or >. | 1402 ** |
1148 ** A >= or > can be used if there is a prior < or <=. | 1403 ** A <= or < can be used if there is a prior >= or >. |
1149 ** A <= or < is disqualified if there is a prior <=, <, or ==. | 1404 ** A >= or > can be used if there is a prior < or <=. |
1150 ** A >= or > is disqualified if there is a prior >=, >, or ==. | 1405 ** A <= or < is disqualified if there is a prior <=, <, or ==. |
1151 ** A == is disqualifed if there is any prior constraint. | 1406 ** A >= or > is disqualified if there is a prior >=, >, or ==. |
1152 */ | 1407 ** A == is disqualifed if there is any prior constraint. |
1153 int j, opmsk; | 1408 */ |
1154 static const unsigned char compatible[] = { 0, 0, 1, 1, 2, 2 }; | 1409 assert( compatible[RTREE_EQ & 7]==0 ); |
1155 assert( compatible[RTREE_EQ & 7]==0 ); | 1410 assert( compatible[RTREE_LT & 7]==1 ); |
1156 assert( compatible[RTREE_LT & 7]==1 ); | 1411 assert( compatible[RTREE_LE & 7]==1 ); |
1157 assert( compatible[RTREE_LE & 7]==1 ); | 1412 assert( compatible[RTREE_GT & 7]==2 ); |
1158 assert( compatible[RTREE_GT & 7]==2 ); | 1413 assert( compatible[RTREE_GE & 7]==2 ); |
1159 assert( compatible[RTREE_GE & 7]==2 ); | 1414 cCol = p->iColumn - 1 + 'a'; |
1160 cCol = p->iColumn - 1 + 'a'; | 1415 opmsk = compatible[op & 7]; |
1161 opmsk = compatible[op & 7]; | 1416 for(j=0; j<iIdx; j+=2){ |
1162 for(j=0; j<iIdx; j+=2){ | 1417 if( zIdxStr[j+1]==cCol && (compatible[zIdxStr[j] & 7] & opmsk)!=0 ){ |
1163 if( zIdxStr[j+1]==cCol && (compatible[zIdxStr[j] & 7] & opmsk)!=0 ){ | 1418 op = 0; |
1164 op = 0; | 1419 break; |
1165 break; | |
1166 } | |
1167 } | 1420 } |
1168 } | 1421 } |
1169 if( op ){ | 1422 if( op ){ |
1170 assert( iIdx<sizeof(zIdxStr)-1 ); | 1423 assert( iIdx<sizeof(zIdxStr)-1 ); |
1171 zIdxStr[iIdx++] = op; | 1424 zIdxStr[iIdx++] = op; |
1172 zIdxStr[iIdx++] = cCol; | 1425 zIdxStr[iIdx++] = cCol; |
1173 pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2); | 1426 pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2); |
1174 pIdxInfo->aConstraintUsage[ii].omit = 1; | 1427 pIdxInfo->aConstraintUsage[ii].omit = 1; |
1175 } | 1428 } |
1176 } | 1429 } |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1264 static float cellOverlap( | 1517 static float cellOverlap( |
1265 Rtree *pRtree, | 1518 Rtree *pRtree, |
1266 RtreeCell *p, | 1519 RtreeCell *p, |
1267 RtreeCell *aCell, | 1520 RtreeCell *aCell, |
1268 int nCell, | 1521 int nCell, |
1269 int iExclude | 1522 int iExclude |
1270 ){ | 1523 ){ |
1271 int ii; | 1524 int ii; |
1272 float overlap = 0.0; | 1525 float overlap = 0.0; |
1273 for(ii=0; ii<nCell; ii++){ | 1526 for(ii=0; ii<nCell; ii++){ |
1274 if( ii!=iExclude ){ | 1527 #if VARIANT_RSTARTREE_CHOOSESUBTREE |
| 1528 if( ii!=iExclude ) |
| 1529 #else |
| 1530 assert( iExclude==-1 ); |
| 1531 #endif |
| 1532 { |
1275 int jj; | 1533 int jj; |
1276 float o = 1.0; | 1534 float o = 1.0; |
1277 for(jj=0; jj<(pRtree->nDim*2); jj+=2){ | 1535 for(jj=0; jj<(pRtree->nDim*2); jj+=2){ |
1278 double x1; | 1536 double x1; |
1279 double x2; | 1537 double x2; |
1280 | 1538 |
1281 x1 = MAX(DCOORD(p->aCoord[jj]), DCOORD(aCell[ii].aCoord[jj])); | 1539 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])); | 1540 x2 = MIN(DCOORD(p->aCoord[jj+1]), DCOORD(aCell[ii].aCoord[jj+1])); |
1283 | 1541 |
1284 if( x2<x1 ){ | 1542 if( x2<x1 ){ |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1357 nodeGetCell(pRtree, pNode, jj, &aCell[jj]); | 1615 nodeGetCell(pRtree, pNode, jj, &aCell[jj]); |
1358 } | 1616 } |
1359 } | 1617 } |
1360 #endif | 1618 #endif |
1361 | 1619 |
1362 /* Select the child node which will be enlarged the least if pCell | 1620 /* Select the child node which will be enlarged the least if pCell |
1363 ** is inserted into it. Resolve ties by choosing the entry with | 1621 ** is inserted into it. Resolve ties by choosing the entry with |
1364 ** the smallest area. | 1622 ** the smallest area. |
1365 */ | 1623 */ |
1366 for(iCell=0; iCell<nCell; iCell++){ | 1624 for(iCell=0; iCell<nCell; iCell++){ |
| 1625 int bBest = 0; |
1367 float growth; | 1626 float growth; |
1368 float area; | 1627 float area; |
1369 float overlap = 0.0; | 1628 float overlap = 0.0; |
1370 nodeGetCell(pRtree, pNode, iCell, &cell); | 1629 nodeGetCell(pRtree, pNode, iCell, &cell); |
1371 growth = cellGrowth(pRtree, &cell, pCell); | 1630 growth = cellGrowth(pRtree, &cell, pCell); |
1372 area = cellArea(pRtree, &cell); | 1631 area = cellArea(pRtree, &cell); |
| 1632 |
1373 #if VARIANT_RSTARTREE_CHOOSESUBTREE | 1633 #if VARIANT_RSTARTREE_CHOOSESUBTREE |
1374 if( ii==(pRtree->iDepth-1) ){ | 1634 if( ii==(pRtree->iDepth-1) ){ |
1375 overlap = cellOverlapEnlargement(pRtree,&cell,pCell,aCell,nCell,iCell); | 1635 overlap = cellOverlapEnlargement(pRtree,&cell,pCell,aCell,nCell,iCell); |
1376 } | 1636 } |
1377 #endif | |
1378 if( (iCell==0) | 1637 if( (iCell==0) |
1379 || (overlap<fMinOverlap) | 1638 || (overlap<fMinOverlap) |
1380 || (overlap==fMinOverlap && growth<fMinGrowth) | 1639 || (overlap==fMinOverlap && growth<fMinGrowth) |
1381 || (overlap==fMinOverlap && growth==fMinGrowth && area<fMinArea) | 1640 || (overlap==fMinOverlap && growth==fMinGrowth && area<fMinArea) |
1382 ){ | 1641 ){ |
| 1642 bBest = 1; |
| 1643 } |
| 1644 #else |
| 1645 if( iCell==0||growth<fMinGrowth||(growth==fMinGrowth && area<fMinArea) ){ |
| 1646 bBest = 1; |
| 1647 } |
| 1648 #endif |
| 1649 if( bBest ){ |
1383 fMinOverlap = overlap; | 1650 fMinOverlap = overlap; |
1384 fMinGrowth = growth; | 1651 fMinGrowth = growth; |
1385 fMinArea = area; | 1652 fMinArea = area; |
1386 iBest = cell.iRowid; | 1653 iBest = cell.iRowid; |
1387 } | 1654 } |
1388 } | 1655 } |
1389 | 1656 |
1390 sqlite3_free(aCell); | 1657 sqlite3_free(aCell); |
1391 rc = nodeAcquire(pRtree, iBest, pNode, &pChild); | 1658 rc = nodeAcquire(pRtree, iBest, pNode, &pChild); |
1392 nodeRelease(pRtree, pNode); | 1659 nodeRelease(pRtree, pNode); |
1393 pNode = pChild; | 1660 pNode = pChild; |
1394 } | 1661 } |
1395 | 1662 |
1396 *ppLeaf = pNode; | 1663 *ppLeaf = pNode; |
1397 return rc; | 1664 return rc; |
1398 } | 1665 } |
1399 | 1666 |
1400 /* | 1667 /* |
1401 ** A cell with the same content as pCell has just been inserted into | 1668 ** 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 | 1669 ** the node pNode. This function updates the bounding box cells in |
1403 ** all ancestor elements. | 1670 ** all ancestor elements. |
1404 */ | 1671 */ |
1405 static void AdjustTree( | 1672 static int AdjustTree( |
1406 Rtree *pRtree, /* Rtree table */ | 1673 Rtree *pRtree, /* Rtree table */ |
1407 RtreeNode *pNode, /* Adjust ancestry of this node. */ | 1674 RtreeNode *pNode, /* Adjust ancestry of this node. */ |
1408 RtreeCell *pCell /* This cell was just inserted */ | 1675 RtreeCell *pCell /* This cell was just inserted */ |
1409 ){ | 1676 ){ |
1410 RtreeNode *p = pNode; | 1677 RtreeNode *p = pNode; |
1411 while( p->pParent ){ | 1678 while( p->pParent ){ |
| 1679 RtreeNode *pParent = p->pParent; |
1412 RtreeCell cell; | 1680 RtreeCell cell; |
1413 RtreeNode *pParent = p->pParent; | 1681 int iCell; |
1414 int iCell = nodeParentIndex(pRtree, p); | 1682 |
| 1683 if( nodeParentIndex(pRtree, p, &iCell) ){ |
| 1684 return SQLITE_CORRUPT; |
| 1685 } |
1415 | 1686 |
1416 nodeGetCell(pRtree, pParent, iCell, &cell); | 1687 nodeGetCell(pRtree, pParent, iCell, &cell); |
1417 if( !cellContains(pRtree, &cell, pCell) ){ | 1688 if( !cellContains(pRtree, &cell, pCell) ){ |
1418 cellUnion(pRtree, &cell, pCell); | 1689 cellUnion(pRtree, &cell, pCell); |
1419 nodeOverwriteCell(pRtree, pParent, &cell, iCell); | 1690 nodeOverwriteCell(pRtree, pParent, &cell, iCell); |
1420 } | 1691 } |
1421 | 1692 |
1422 p = pParent; | 1693 p = pParent; |
1423 } | 1694 } |
| 1695 return SQLITE_OK; |
1424 } | 1696 } |
1425 | 1697 |
1426 /* | 1698 /* |
1427 ** Write mapping (iRowid->iNode) to the <rtree>_rowid table. | 1699 ** Write mapping (iRowid->iNode) to the <rtree>_rowid table. |
1428 */ | 1700 */ |
1429 static int rowidWrite(Rtree *pRtree, sqlite3_int64 iRowid, sqlite3_int64 iNode){ | 1701 static int rowidWrite(Rtree *pRtree, sqlite3_int64 iRowid, sqlite3_int64 iNode){ |
1430 sqlite3_bind_int64(pRtree->pWriteRowid, 1, iRowid); | 1702 sqlite3_bind_int64(pRtree->pWriteRowid, 1, iRowid); |
1431 sqlite3_bind_int64(pRtree->pWriteRowid, 2, iNode); | 1703 sqlite3_bind_int64(pRtree->pWriteRowid, 2, iNode); |
1432 sqlite3_step(pRtree->pWriteRowid); | 1704 sqlite3_step(pRtree->pWriteRowid); |
1433 return sqlite3_reset(pRtree->pWriteRowid); | 1705 return sqlite3_reset(pRtree->pWriteRowid); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1479 int iLeftSeed = 0; | 1751 int iLeftSeed = 0; |
1480 int iRightSeed = 1; | 1752 int iRightSeed = 1; |
1481 float maxNormalInnerWidth = 0.0; | 1753 float maxNormalInnerWidth = 0.0; |
1482 | 1754 |
1483 /* Pick two "seed" cells from the array of cells. The algorithm used | 1755 /* Pick two "seed" cells from the array of cells. The algorithm used |
1484 ** here is the LinearPickSeeds algorithm from Gutman[1984]. The | 1756 ** here is the LinearPickSeeds algorithm from Gutman[1984]. The |
1485 ** indices of the two seed cells in the array are stored in local | 1757 ** indices of the two seed cells in the array are stored in local |
1486 ** variables iLeftSeek and iRightSeed. | 1758 ** variables iLeftSeek and iRightSeed. |
1487 */ | 1759 */ |
1488 for(i=0; i<pRtree->nDim; i++){ | 1760 for(i=0; i<pRtree->nDim; i++){ |
1489 float x1 = aCell[0].aCoord[i*2]; | 1761 float x1 = DCOORD(aCell[0].aCoord[i*2]); |
1490 float x2 = aCell[0].aCoord[i*2+1]; | 1762 float x2 = DCOORD(aCell[0].aCoord[i*2+1]); |
1491 float x3 = x1; | 1763 float x3 = x1; |
1492 float x4 = x2; | 1764 float x4 = x2; |
1493 int jj; | 1765 int jj; |
1494 | 1766 |
1495 int iCellLeft = 0; | 1767 int iCellLeft = 0; |
1496 int iCellRight = 0; | 1768 int iCellRight = 0; |
1497 | 1769 |
1498 for(jj=1; jj<nCell; jj++){ | 1770 for(jj=1; jj<nCell; jj++){ |
1499 float left = aCell[jj].aCoord[i*2]; | 1771 float left = DCOORD(aCell[jj].aCoord[i*2]); |
1500 float right = aCell[jj].aCoord[i*2+1]; | 1772 float right = DCOORD(aCell[jj].aCoord[i*2+1]); |
1501 | 1773 |
1502 if( left<x1 ) x1 = left; | 1774 if( left<x1 ) x1 = left; |
1503 if( right>x4 ) x4 = right; | 1775 if( right>x4 ) x4 = right; |
1504 if( left>x3 ){ | 1776 if( left>x3 ){ |
1505 x3 = left; | 1777 x3 = left; |
1506 iCellRight = jj; | 1778 iCellRight = jj; |
1507 } | 1779 } |
1508 if( right<x2 ){ | 1780 if( right<x2 ){ |
1509 x2 = right; | 1781 x2 = right; |
1510 iCellLeft = jj; | 1782 iCellLeft = jj; |
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1848 RtreeNode *pRight, | 2120 RtreeNode *pRight, |
1849 RtreeCell *pBboxLeft, | 2121 RtreeCell *pBboxLeft, |
1850 RtreeCell *pBboxRight | 2122 RtreeCell *pBboxRight |
1851 ){ | 2123 ){ |
1852 int iLeftSeed = 0; | 2124 int iLeftSeed = 0; |
1853 int iRightSeed = 1; | 2125 int iRightSeed = 1; |
1854 int *aiUsed; | 2126 int *aiUsed; |
1855 int i; | 2127 int i; |
1856 | 2128 |
1857 aiUsed = sqlite3_malloc(sizeof(int)*nCell); | 2129 aiUsed = sqlite3_malloc(sizeof(int)*nCell); |
| 2130 if( !aiUsed ){ |
| 2131 return SQLITE_NOMEM; |
| 2132 } |
1858 memset(aiUsed, 0, sizeof(int)*nCell); | 2133 memset(aiUsed, 0, sizeof(int)*nCell); |
1859 | 2134 |
1860 PickSeeds(pRtree, aCell, nCell, &iLeftSeed, &iRightSeed); | 2135 PickSeeds(pRtree, aCell, nCell, &iLeftSeed, &iRightSeed); |
1861 | 2136 |
1862 memcpy(pBboxLeft, &aCell[iLeftSeed], sizeof(RtreeCell)); | 2137 memcpy(pBboxLeft, &aCell[iLeftSeed], sizeof(RtreeCell)); |
1863 memcpy(pBboxRight, &aCell[iRightSeed], sizeof(RtreeCell)); | 2138 memcpy(pBboxRight, &aCell[iRightSeed], sizeof(RtreeCell)); |
1864 nodeInsertCell(pRtree, pLeft, &aCell[iLeftSeed]); | 2139 nodeInsertCell(pRtree, pLeft, &aCell[iLeftSeed]); |
1865 nodeInsertCell(pRtree, pRight, &aCell[iRightSeed]); | 2140 nodeInsertCell(pRtree, pRight, &aCell[iRightSeed]); |
1866 aiUsed[iLeftSeed] = 1; | 2141 aiUsed[iLeftSeed] = 1; |
1867 aiUsed[iRightSeed] = 1; | 2142 aiUsed[iRightSeed] = 1; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1939 aiUsed = (int *)&aCell[nCell+1]; | 2214 aiUsed = (int *)&aCell[nCell+1]; |
1940 memset(aiUsed, 0, sizeof(int)*(nCell+1)); | 2215 memset(aiUsed, 0, sizeof(int)*(nCell+1)); |
1941 for(i=0; i<nCell; i++){ | 2216 for(i=0; i<nCell; i++){ |
1942 nodeGetCell(pRtree, pNode, i, &aCell[i]); | 2217 nodeGetCell(pRtree, pNode, i, &aCell[i]); |
1943 } | 2218 } |
1944 nodeZero(pRtree, pNode); | 2219 nodeZero(pRtree, pNode); |
1945 memcpy(&aCell[nCell], pCell, sizeof(RtreeCell)); | 2220 memcpy(&aCell[nCell], pCell, sizeof(RtreeCell)); |
1946 nCell++; | 2221 nCell++; |
1947 | 2222 |
1948 if( pNode->iNode==1 ){ | 2223 if( pNode->iNode==1 ){ |
1949 pRight = nodeNew(pRtree, pNode, 1); | 2224 pRight = nodeNew(pRtree, pNode); |
1950 pLeft = nodeNew(pRtree, pNode, 1); | 2225 pLeft = nodeNew(pRtree, pNode); |
1951 pRtree->iDepth++; | 2226 pRtree->iDepth++; |
1952 pNode->isDirty = 1; | 2227 pNode->isDirty = 1; |
1953 writeInt16(pNode->zData, pRtree->iDepth); | 2228 writeInt16(pNode->zData, pRtree->iDepth); |
1954 }else{ | 2229 }else{ |
1955 pLeft = pNode; | 2230 pLeft = pNode; |
1956 pRight = nodeNew(pRtree, pLeft->pParent, 1); | 2231 pRight = nodeNew(pRtree, pLeft->pParent); |
1957 nodeReference(pLeft); | 2232 nodeReference(pLeft); |
1958 } | 2233 } |
1959 | 2234 |
1960 if( !pLeft || !pRight ){ | 2235 if( !pLeft || !pRight ){ |
1961 rc = SQLITE_NOMEM; | 2236 rc = SQLITE_NOMEM; |
1962 goto splitnode_out; | 2237 goto splitnode_out; |
1963 } | 2238 } |
1964 | 2239 |
1965 memset(pLeft->zData, 0, pRtree->iNodeSize); | 2240 memset(pLeft->zData, 0, pRtree->iNodeSize); |
1966 memset(pRight->zData, 0, pRtree->iNodeSize); | 2241 memset(pRight->zData, 0, pRtree->iNodeSize); |
1967 | 2242 |
1968 rc = AssignCells(pRtree, aCell, nCell, pLeft, pRight, &leftbbox, &rightbbox); | 2243 rc = AssignCells(pRtree, aCell, nCell, pLeft, pRight, &leftbbox, &rightbbox); |
1969 if( rc!=SQLITE_OK ){ | 2244 if( rc!=SQLITE_OK ){ |
1970 goto splitnode_out; | 2245 goto splitnode_out; |
1971 } | 2246 } |
1972 | 2247 |
1973 /* Ensure both child nodes have node numbers assigned to them. */ | 2248 /* Ensure both child nodes have node numbers assigned to them by calling |
1974 if( (0==pRight->iNode && SQLITE_OK!=(rc = nodeWrite(pRtree, pRight))) | 2249 ** nodeWrite(). Node pRight always needs a node number, as it was created |
| 2250 ** by nodeNew() above. But node pLeft sometimes already has a node number. |
| 2251 ** In this case avoid the all to nodeWrite(). |
| 2252 */ |
| 2253 if( SQLITE_OK!=(rc = nodeWrite(pRtree, pRight)) |
1975 || (0==pLeft->iNode && SQLITE_OK!=(rc = nodeWrite(pRtree, pLeft))) | 2254 || (0==pLeft->iNode && SQLITE_OK!=(rc = nodeWrite(pRtree, pLeft))) |
1976 ){ | 2255 ){ |
1977 goto splitnode_out; | 2256 goto splitnode_out; |
1978 } | 2257 } |
1979 | 2258 |
1980 rightbbox.iRowid = pRight->iNode; | 2259 rightbbox.iRowid = pRight->iNode; |
1981 leftbbox.iRowid = pLeft->iNode; | 2260 leftbbox.iRowid = pLeft->iNode; |
1982 | 2261 |
1983 if( pNode->iNode==1 ){ | 2262 if( pNode->iNode==1 ){ |
1984 rc = rtreeInsertCell(pRtree, pLeft->pParent, &leftbbox, iHeight+1); | 2263 rc = rtreeInsertCell(pRtree, pLeft->pParent, &leftbbox, iHeight+1); |
1985 if( rc!=SQLITE_OK ){ | 2264 if( rc!=SQLITE_OK ){ |
1986 goto splitnode_out; | 2265 goto splitnode_out; |
1987 } | 2266 } |
1988 }else{ | 2267 }else{ |
1989 RtreeNode *pParent = pLeft->pParent; | 2268 RtreeNode *pParent = pLeft->pParent; |
1990 int iCell = nodeParentIndex(pRtree, pLeft); | 2269 int iCell; |
1991 nodeOverwriteCell(pRtree, pParent, &leftbbox, iCell); | 2270 rc = nodeParentIndex(pRtree, pLeft, &iCell); |
1992 AdjustTree(pRtree, pParent, &leftbbox); | 2271 if( rc==SQLITE_OK ){ |
| 2272 nodeOverwriteCell(pRtree, pParent, &leftbbox, iCell); |
| 2273 rc = AdjustTree(pRtree, pParent, &leftbbox); |
| 2274 } |
| 2275 if( rc!=SQLITE_OK ){ |
| 2276 goto splitnode_out; |
| 2277 } |
1993 } | 2278 } |
1994 if( (rc = rtreeInsertCell(pRtree, pRight->pParent, &rightbbox, iHeight+1)) ){ | 2279 if( (rc = rtreeInsertCell(pRtree, pRight->pParent, &rightbbox, iHeight+1)) ){ |
1995 goto splitnode_out; | 2280 goto splitnode_out; |
1996 } | 2281 } |
1997 | 2282 |
1998 for(i=0; i<NCELL(pRight); i++){ | 2283 for(i=0; i<NCELL(pRight); i++){ |
1999 i64 iRowid = nodeGetRowid(pRtree, pRight, i); | 2284 i64 iRowid = nodeGetRowid(pRtree, pRight, i); |
2000 rc = updateMapping(pRtree, iRowid, pRight, iHeight); | 2285 rc = updateMapping(pRtree, iRowid, pRight, iHeight); |
2001 if( iRowid==pCell->iRowid ){ | 2286 if( iRowid==pCell->iRowid ){ |
2002 newCellIsRight = 1; | 2287 newCellIsRight = 1; |
(...skipping 23 matching lines...) Expand all Loading... |
2026 pLeft = 0; | 2311 pLeft = 0; |
2027 } | 2312 } |
2028 | 2313 |
2029 splitnode_out: | 2314 splitnode_out: |
2030 nodeRelease(pRtree, pRight); | 2315 nodeRelease(pRtree, pRight); |
2031 nodeRelease(pRtree, pLeft); | 2316 nodeRelease(pRtree, pLeft); |
2032 sqlite3_free(aCell); | 2317 sqlite3_free(aCell); |
2033 return rc; | 2318 return rc; |
2034 } | 2319 } |
2035 | 2320 |
| 2321 /* |
| 2322 ** If node pLeaf is not the root of the r-tree and its pParent pointer is |
| 2323 ** still NULL, load all ancestor nodes of pLeaf into memory and populate |
| 2324 ** the pLeaf->pParent chain all the way up to the root node. |
| 2325 ** |
| 2326 ** This operation is required when a row is deleted (or updated - an update |
| 2327 ** is implemented as a delete followed by an insert). SQLite provides the |
| 2328 ** rowid of the row to delete, which can be used to find the leaf on which |
| 2329 ** the entry resides (argument pLeaf). Once the leaf is located, this |
| 2330 ** function is called to determine its ancestry. |
| 2331 */ |
2036 static int fixLeafParent(Rtree *pRtree, RtreeNode *pLeaf){ | 2332 static int fixLeafParent(Rtree *pRtree, RtreeNode *pLeaf){ |
2037 int rc = SQLITE_OK; | 2333 int rc = SQLITE_OK; |
2038 if( pLeaf->iNode!=1 && pLeaf->pParent==0 ){ | 2334 RtreeNode *pChild = pLeaf; |
2039 sqlite3_bind_int64(pRtree->pReadParent, 1, pLeaf->iNode); | 2335 while( rc==SQLITE_OK && pChild->iNode!=1 && pChild->pParent==0 ){ |
2040 if( sqlite3_step(pRtree->pReadParent)==SQLITE_ROW ){ | 2336 int rc2 = SQLITE_OK; /* sqlite3_reset() return code */ |
2041 i64 iNode = sqlite3_column_int64(pRtree->pReadParent, 0); | 2337 sqlite3_bind_int64(pRtree->pReadParent, 1, pChild->iNode); |
2042 rc = nodeAcquire(pRtree, iNode, 0, &pLeaf->pParent); | 2338 rc = sqlite3_step(pRtree->pReadParent); |
2043 }else{ | 2339 if( rc==SQLITE_ROW ){ |
2044 rc = SQLITE_ERROR; | 2340 RtreeNode *pTest; /* Used to test for reference loops */ |
| 2341 i64 iNode; /* Node number of parent node */ |
| 2342 |
| 2343 /* Before setting pChild->pParent, test that we are not creating a |
| 2344 ** loop of references (as we would if, say, pChild==pParent). We don't |
| 2345 ** want to do this as it leads to a memory leak when trying to delete |
| 2346 ** the referenced counted node structures. |
| 2347 */ |
| 2348 iNode = sqlite3_column_int64(pRtree->pReadParent, 0); |
| 2349 for(pTest=pLeaf; pTest && pTest->iNode!=iNode; pTest=pTest->pParent); |
| 2350 if( !pTest ){ |
| 2351 rc2 = nodeAcquire(pRtree, iNode, 0, &pChild->pParent); |
| 2352 } |
2045 } | 2353 } |
2046 sqlite3_reset(pRtree->pReadParent); | 2354 rc = sqlite3_reset(pRtree->pReadParent); |
2047 if( rc==SQLITE_OK ){ | 2355 if( rc==SQLITE_OK ) rc = rc2; |
2048 rc = fixLeafParent(pRtree, pLeaf->pParent); | 2356 if( rc==SQLITE_OK && !pChild->pParent ) rc = SQLITE_CORRUPT; |
2049 } | 2357 pChild = pChild->pParent; |
2050 } | 2358 } |
2051 return rc; | 2359 return rc; |
2052 } | 2360 } |
2053 | 2361 |
2054 static int deleteCell(Rtree *, RtreeNode *, int, int); | 2362 static int deleteCell(Rtree *, RtreeNode *, int, int); |
2055 | 2363 |
2056 static int removeNode(Rtree *pRtree, RtreeNode *pNode, int iHeight){ | 2364 static int removeNode(Rtree *pRtree, RtreeNode *pNode, int iHeight){ |
2057 int rc; | 2365 int rc; |
| 2366 int rc2; |
2058 RtreeNode *pParent; | 2367 RtreeNode *pParent; |
2059 int iCell; | 2368 int iCell; |
2060 | 2369 |
2061 assert( pNode->nRef==1 ); | 2370 assert( pNode->nRef==1 ); |
2062 | 2371 |
2063 /* Remove the entry in the parent cell. */ | 2372 /* Remove the entry in the parent cell. */ |
2064 iCell = nodeParentIndex(pRtree, pNode); | 2373 rc = nodeParentIndex(pRtree, pNode, &iCell); |
2065 pParent = pNode->pParent; | 2374 if( rc==SQLITE_OK ){ |
2066 pNode->pParent = 0; | 2375 pParent = pNode->pParent; |
2067 if( SQLITE_OK!=(rc = deleteCell(pRtree, pParent, iCell, iHeight+1)) | 2376 pNode->pParent = 0; |
2068 || SQLITE_OK!=(rc = nodeRelease(pRtree, pParent)) | 2377 rc = deleteCell(pRtree, pParent, iCell, iHeight+1); |
2069 ){ | 2378 } |
| 2379 rc2 = nodeRelease(pRtree, pParent); |
| 2380 if( rc==SQLITE_OK ){ |
| 2381 rc = rc2; |
| 2382 } |
| 2383 if( rc!=SQLITE_OK ){ |
2070 return rc; | 2384 return rc; |
2071 } | 2385 } |
2072 | 2386 |
2073 /* Remove the xxx_node entry. */ | 2387 /* Remove the xxx_node entry. */ |
2074 sqlite3_bind_int64(pRtree->pDeleteNode, 1, pNode->iNode); | 2388 sqlite3_bind_int64(pRtree->pDeleteNode, 1, pNode->iNode); |
2075 sqlite3_step(pRtree->pDeleteNode); | 2389 sqlite3_step(pRtree->pDeleteNode); |
2076 if( SQLITE_OK!=(rc = sqlite3_reset(pRtree->pDeleteNode)) ){ | 2390 if( SQLITE_OK!=(rc = sqlite3_reset(pRtree->pDeleteNode)) ){ |
2077 return rc; | 2391 return rc; |
2078 } | 2392 } |
2079 | 2393 |
2080 /* Remove the xxx_parent entry. */ | 2394 /* Remove the xxx_parent entry. */ |
2081 sqlite3_bind_int64(pRtree->pDeleteParent, 1, pNode->iNode); | 2395 sqlite3_bind_int64(pRtree->pDeleteParent, 1, pNode->iNode); |
2082 sqlite3_step(pRtree->pDeleteParent); | 2396 sqlite3_step(pRtree->pDeleteParent); |
2083 if( SQLITE_OK!=(rc = sqlite3_reset(pRtree->pDeleteParent)) ){ | 2397 if( SQLITE_OK!=(rc = sqlite3_reset(pRtree->pDeleteParent)) ){ |
2084 return rc; | 2398 return rc; |
2085 } | 2399 } |
2086 | 2400 |
2087 /* Remove the node from the in-memory hash table and link it into | 2401 /* 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. | 2402 ** the Rtree.pDeleted list. Its contents will be re-inserted later on. |
2089 */ | 2403 */ |
2090 nodeHashDelete(pRtree, pNode); | 2404 nodeHashDelete(pRtree, pNode); |
2091 pNode->iNode = iHeight; | 2405 pNode->iNode = iHeight; |
2092 pNode->pNext = pRtree->pDeleted; | 2406 pNode->pNext = pRtree->pDeleted; |
2093 pNode->nRef++; | 2407 pNode->nRef++; |
2094 pRtree->pDeleted = pNode; | 2408 pRtree->pDeleted = pNode; |
2095 | 2409 |
2096 return SQLITE_OK; | 2410 return SQLITE_OK; |
2097 } | 2411 } |
2098 | 2412 |
2099 static void fixBoundingBox(Rtree *pRtree, RtreeNode *pNode){ | 2413 static int fixBoundingBox(Rtree *pRtree, RtreeNode *pNode){ |
2100 RtreeNode *pParent = pNode->pParent; | 2414 RtreeNode *pParent = pNode->pParent; |
| 2415 int rc = SQLITE_OK; |
2101 if( pParent ){ | 2416 if( pParent ){ |
2102 int ii; | 2417 int ii; |
2103 int nCell = NCELL(pNode); | 2418 int nCell = NCELL(pNode); |
2104 RtreeCell box; /* Bounding box for pNode */ | 2419 RtreeCell box; /* Bounding box for pNode */ |
2105 nodeGetCell(pRtree, pNode, 0, &box); | 2420 nodeGetCell(pRtree, pNode, 0, &box); |
2106 for(ii=1; ii<nCell; ii++){ | 2421 for(ii=1; ii<nCell; ii++){ |
2107 RtreeCell cell; | 2422 RtreeCell cell; |
2108 nodeGetCell(pRtree, pNode, ii, &cell); | 2423 nodeGetCell(pRtree, pNode, ii, &cell); |
2109 cellUnion(pRtree, &box, &cell); | 2424 cellUnion(pRtree, &box, &cell); |
2110 } | 2425 } |
2111 box.iRowid = pNode->iNode; | 2426 box.iRowid = pNode->iNode; |
2112 ii = nodeParentIndex(pRtree, pNode); | 2427 rc = nodeParentIndex(pRtree, pNode, &ii); |
2113 nodeOverwriteCell(pRtree, pParent, &box, ii); | 2428 if( rc==SQLITE_OK ){ |
2114 fixBoundingBox(pRtree, pParent); | 2429 nodeOverwriteCell(pRtree, pParent, &box, ii); |
| 2430 rc = fixBoundingBox(pRtree, pParent); |
| 2431 } |
2115 } | 2432 } |
| 2433 return rc; |
2116 } | 2434 } |
2117 | 2435 |
2118 /* | 2436 /* |
2119 ** Delete the cell at index iCell of node pNode. After removing the | 2437 ** Delete the cell at index iCell of node pNode. After removing the |
2120 ** cell, adjust the r-tree data structure if required. | 2438 ** cell, adjust the r-tree data structure if required. |
2121 */ | 2439 */ |
2122 static int deleteCell(Rtree *pRtree, RtreeNode *pNode, int iCell, int iHeight){ | 2440 static int deleteCell(Rtree *pRtree, RtreeNode *pNode, int iCell, int iHeight){ |
| 2441 RtreeNode *pParent; |
2123 int rc; | 2442 int rc; |
2124 | 2443 |
2125 if( SQLITE_OK!=(rc = fixLeafParent(pRtree, pNode)) ){ | 2444 if( SQLITE_OK!=(rc = fixLeafParent(pRtree, pNode)) ){ |
2126 return rc; | 2445 return rc; |
2127 } | 2446 } |
2128 | 2447 |
2129 /* Remove the cell from the node. This call just moves bytes around | 2448 /* Remove the cell from the node. This call just moves bytes around |
2130 ** the in-memory node image, so it cannot fail. | 2449 ** the in-memory node image, so it cannot fail. |
2131 */ | 2450 */ |
2132 nodeDeleteCell(pRtree, pNode, iCell); | 2451 nodeDeleteCell(pRtree, pNode, iCell); |
2133 | 2452 |
2134 /* If the node is not the tree root and now has less than the minimum | 2453 /* 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 | 2454 ** number of cells, remove it from the tree. Otherwise, update the |
2136 ** cell in the parent node so that it tightly contains the updated | 2455 ** cell in the parent node so that it tightly contains the updated |
2137 ** node. | 2456 ** node. |
2138 */ | 2457 */ |
2139 if( pNode->iNode!=1 ){ | 2458 pParent = pNode->pParent; |
2140 RtreeNode *pParent = pNode->pParent; | 2459 assert( pParent || pNode->iNode==1 ); |
2141 if( (pParent->iNode!=1 || NCELL(pParent)!=1) | 2460 if( pParent ){ |
2142 && (NCELL(pNode)<RTREE_MINCELLS(pRtree)) | 2461 if( NCELL(pNode)<RTREE_MINCELLS(pRtree) ){ |
2143 ){ | |
2144 rc = removeNode(pRtree, pNode, iHeight); | 2462 rc = removeNode(pRtree, pNode, iHeight); |
2145 }else{ | 2463 }else{ |
2146 fixBoundingBox(pRtree, pNode); | 2464 rc = fixBoundingBox(pRtree, pNode); |
2147 } | 2465 } |
2148 } | 2466 } |
2149 | 2467 |
2150 return rc; | 2468 return rc; |
2151 } | 2469 } |
2152 | 2470 |
2153 static int Reinsert( | 2471 static int Reinsert( |
2154 Rtree *pRtree, | 2472 Rtree *pRtree, |
2155 RtreeNode *pNode, | 2473 RtreeNode *pNode, |
2156 RtreeCell *pCell, | 2474 RtreeCell *pCell, |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2219 nodeInsertCell(pRtree, pNode, p); | 2537 nodeInsertCell(pRtree, pNode, p); |
2220 if( p->iRowid==pCell->iRowid ){ | 2538 if( p->iRowid==pCell->iRowid ){ |
2221 if( iHeight==0 ){ | 2539 if( iHeight==0 ){ |
2222 rc = rowidWrite(pRtree, p->iRowid, pNode->iNode); | 2540 rc = rowidWrite(pRtree, p->iRowid, pNode->iNode); |
2223 }else{ | 2541 }else{ |
2224 rc = parentWrite(pRtree, p->iRowid, pNode->iNode); | 2542 rc = parentWrite(pRtree, p->iRowid, pNode->iNode); |
2225 } | 2543 } |
2226 } | 2544 } |
2227 } | 2545 } |
2228 if( rc==SQLITE_OK ){ | 2546 if( rc==SQLITE_OK ){ |
2229 fixBoundingBox(pRtree, pNode); | 2547 rc = fixBoundingBox(pRtree, pNode); |
2230 } | 2548 } |
2231 for(; rc==SQLITE_OK && ii<nCell; ii++){ | 2549 for(; rc==SQLITE_OK && ii<nCell; ii++){ |
2232 /* Find a node to store this cell in. pNode->iNode currently contains | 2550 /* Find a node to store this cell in. pNode->iNode currently contains |
2233 ** the height of the sub-tree headed by the cell. | 2551 ** the height of the sub-tree headed by the cell. |
2234 */ | 2552 */ |
2235 RtreeNode *pInsert; | 2553 RtreeNode *pInsert; |
2236 RtreeCell *p = &aCell[aOrder[ii]]; | 2554 RtreeCell *p = &aCell[aOrder[ii]]; |
2237 rc = ChooseLeaf(pRtree, p, iHeight, &pInsert); | 2555 rc = ChooseLeaf(pRtree, p, iHeight, &pInsert); |
2238 if( rc==SQLITE_OK ){ | 2556 if( rc==SQLITE_OK ){ |
2239 int rc2; | 2557 int rc2; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2273 if( iHeight<=pRtree->iReinsertHeight || pNode->iNode==1){ | 2591 if( iHeight<=pRtree->iReinsertHeight || pNode->iNode==1){ |
2274 rc = SplitNode(pRtree, pNode, pCell, iHeight); | 2592 rc = SplitNode(pRtree, pNode, pCell, iHeight); |
2275 }else{ | 2593 }else{ |
2276 pRtree->iReinsertHeight = iHeight; | 2594 pRtree->iReinsertHeight = iHeight; |
2277 rc = Reinsert(pRtree, pNode, pCell, iHeight); | 2595 rc = Reinsert(pRtree, pNode, pCell, iHeight); |
2278 } | 2596 } |
2279 #else | 2597 #else |
2280 rc = SplitNode(pRtree, pNode, pCell, iHeight); | 2598 rc = SplitNode(pRtree, pNode, pCell, iHeight); |
2281 #endif | 2599 #endif |
2282 }else{ | 2600 }else{ |
2283 AdjustTree(pRtree, pNode, pCell); | 2601 rc = AdjustTree(pRtree, pNode, pCell); |
2284 if( iHeight==0 ){ | 2602 if( rc==SQLITE_OK ){ |
2285 rc = rowidWrite(pRtree, pCell->iRowid, pNode->iNode); | 2603 if( iHeight==0 ){ |
2286 }else{ | 2604 rc = rowidWrite(pRtree, pCell->iRowid, pNode->iNode); |
2287 rc = parentWrite(pRtree, pCell->iRowid, pNode->iNode); | 2605 }else{ |
| 2606 rc = parentWrite(pRtree, pCell->iRowid, pNode->iNode); |
| 2607 } |
2288 } | 2608 } |
2289 } | 2609 } |
2290 return rc; | 2610 return rc; |
2291 } | 2611 } |
2292 | 2612 |
2293 static int reinsertNodeContent(Rtree *pRtree, RtreeNode *pNode){ | 2613 static int reinsertNodeContent(Rtree *pRtree, RtreeNode *pNode){ |
2294 int ii; | 2614 int ii; |
2295 int rc = SQLITE_OK; | 2615 int rc = SQLITE_OK; |
2296 int nCell = NCELL(pNode); | 2616 int nCell = NCELL(pNode); |
2297 | 2617 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2347 int nData, | 2667 int nData, |
2348 sqlite3_value **azData, | 2668 sqlite3_value **azData, |
2349 sqlite_int64 *pRowid | 2669 sqlite_int64 *pRowid |
2350 ){ | 2670 ){ |
2351 Rtree *pRtree = (Rtree *)pVtab; | 2671 Rtree *pRtree = (Rtree *)pVtab; |
2352 int rc = SQLITE_OK; | 2672 int rc = SQLITE_OK; |
2353 | 2673 |
2354 rtreeReference(pRtree); | 2674 rtreeReference(pRtree); |
2355 | 2675 |
2356 assert(nData>=1); | 2676 assert(nData>=1); |
2357 assert(hashIsEmpty(pRtree)); | |
2358 | 2677 |
2359 /* If azData[0] is not an SQL NULL value, it is the rowid of a | 2678 /* 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 | 2679 ** record to delete from the r-tree table. The following block does |
2361 ** just that. | 2680 ** just that. |
2362 */ | 2681 */ |
2363 if( sqlite3_value_type(azData[0])!=SQLITE_NULL ){ | 2682 if( sqlite3_value_type(azData[0])!=SQLITE_NULL ){ |
2364 i64 iDelete; /* The rowid to delete */ | 2683 i64 iDelete; /* The rowid to delete */ |
2365 RtreeNode *pLeaf; /* Leaf node containing record iDelete */ | 2684 RtreeNode *pLeaf; /* Leaf node containing record iDelete */ |
2366 int iCell; /* Index of iDelete cell in pLeaf */ | 2685 int iCell; /* Index of iDelete cell in pLeaf */ |
2367 RtreeNode *pRoot; | 2686 RtreeNode *pRoot; |
2368 | 2687 |
2369 /* Obtain a reference to the root node to initialise Rtree.iDepth */ | 2688 /* Obtain a reference to the root node to initialise Rtree.iDepth */ |
2370 rc = nodeAcquire(pRtree, 1, 0, &pRoot); | 2689 rc = nodeAcquire(pRtree, 1, 0, &pRoot); |
2371 | 2690 |
2372 /* Obtain a reference to the leaf node that contains the entry | 2691 /* Obtain a reference to the leaf node that contains the entry |
2373 ** about to be deleted. | 2692 ** about to be deleted. |
2374 */ | 2693 */ |
2375 if( rc==SQLITE_OK ){ | 2694 if( rc==SQLITE_OK ){ |
2376 iDelete = sqlite3_value_int64(azData[0]); | 2695 iDelete = sqlite3_value_int64(azData[0]); |
2377 rc = findLeafNode(pRtree, iDelete, &pLeaf); | 2696 rc = findLeafNode(pRtree, iDelete, &pLeaf); |
2378 } | 2697 } |
2379 | 2698 |
2380 /* Delete the cell in question from the leaf node. */ | 2699 /* Delete the cell in question from the leaf node. */ |
2381 if( rc==SQLITE_OK ){ | 2700 if( rc==SQLITE_OK ){ |
2382 int rc2; | 2701 int rc2; |
2383 iCell = nodeRowidIndex(pRtree, pLeaf, iDelete); | 2702 rc = nodeRowidIndex(pRtree, pLeaf, iDelete, &iCell); |
2384 rc = deleteCell(pRtree, pLeaf, iCell, 0); | 2703 if( rc==SQLITE_OK ){ |
| 2704 rc = deleteCell(pRtree, pLeaf, iCell, 0); |
| 2705 } |
2385 rc2 = nodeRelease(pRtree, pLeaf); | 2706 rc2 = nodeRelease(pRtree, pLeaf); |
2386 if( rc==SQLITE_OK ){ | 2707 if( rc==SQLITE_OK ){ |
2387 rc = rc2; | 2708 rc = rc2; |
2388 } | 2709 } |
2389 } | 2710 } |
2390 | 2711 |
2391 /* Delete the corresponding entry in the <rtree>_rowid table. */ | 2712 /* Delete the corresponding entry in the <rtree>_rowid table. */ |
2392 if( rc==SQLITE_OK ){ | 2713 if( rc==SQLITE_OK ){ |
2393 sqlite3_bind_int64(pRtree->pDeleteRowid, 1, iDelete); | 2714 sqlite3_bind_int64(pRtree->pDeleteRowid, 1, iDelete); |
2394 sqlite3_step(pRtree->pDeleteRowid); | 2715 sqlite3_step(pRtree->pDeleteRowid); |
2395 rc = sqlite3_reset(pRtree->pDeleteRowid); | 2716 rc = sqlite3_reset(pRtree->pDeleteRowid); |
2396 } | 2717 } |
2397 | 2718 |
2398 /* Check if the root node now has exactly one child. If so, remove | 2719 /* Check if the root node now has exactly one child. If so, remove |
2399 ** it, schedule the contents of the child for reinsertion and | 2720 ** it, schedule the contents of the child for reinsertion and |
2400 ** reduce the tree height by one. | 2721 ** reduce the tree height by one. |
2401 ** | 2722 ** |
2402 ** This is equivalent to copying the contents of the child into | 2723 ** This is equivalent to copying the contents of the child into |
2403 ** the root node (the operation that Gutman's paper says to perform | 2724 ** the root node (the operation that Gutman's paper says to perform |
2404 ** in this scenario). | 2725 ** in this scenario). |
2405 */ | 2726 */ |
2406 if( rc==SQLITE_OK && pRtree->iDepth>0 ){ | 2727 if( rc==SQLITE_OK && pRtree->iDepth>0 && NCELL(pRoot)==1 ){ |
2407 if( rc==SQLITE_OK && NCELL(pRoot)==1 ){ | 2728 int rc2; |
2408 RtreeNode *pChild; | 2729 RtreeNode *pChild; |
2409 i64 iChild = nodeGetRowid(pRtree, pRoot, 0); | 2730 i64 iChild = nodeGetRowid(pRtree, pRoot, 0); |
2410 rc = nodeAcquire(pRtree, iChild, pRoot, &pChild); | 2731 rc = nodeAcquire(pRtree, iChild, pRoot, &pChild); |
2411 if( rc==SQLITE_OK ){ | 2732 if( rc==SQLITE_OK ){ |
2412 rc = removeNode(pRtree, pChild, pRtree->iDepth-1); | 2733 rc = removeNode(pRtree, pChild, pRtree->iDepth-1); |
2413 } | 2734 } |
2414 if( rc==SQLITE_OK ){ | 2735 rc2 = nodeRelease(pRtree, pChild); |
2415 pRtree->iDepth--; | 2736 if( rc==SQLITE_OK ) rc = rc2; |
2416 writeInt16(pRoot->zData, pRtree->iDepth); | 2737 if( rc==SQLITE_OK ){ |
2417 pRoot->isDirty = 1; | 2738 pRtree->iDepth--; |
2418 } | 2739 writeInt16(pRoot->zData, pRtree->iDepth); |
| 2740 pRoot->isDirty = 1; |
2419 } | 2741 } |
2420 } | 2742 } |
2421 | 2743 |
2422 /* Re-insert the contents of any underfull nodes removed from the tree. */ | 2744 /* Re-insert the contents of any underfull nodes removed from the tree. */ |
2423 for(pLeaf=pRtree->pDeleted; pLeaf; pLeaf=pRtree->pDeleted){ | 2745 for(pLeaf=pRtree->pDeleted; pLeaf; pLeaf=pRtree->pDeleted){ |
2424 if( rc==SQLITE_OK ){ | 2746 if( rc==SQLITE_OK ){ |
2425 rc = reinsertNodeContent(pRtree, pLeaf); | 2747 rc = reinsertNodeContent(pRtree, pLeaf); |
2426 } | 2748 } |
2427 pRtree->pDeleted = pLeaf->pNext; | 2749 pRtree->pDeleted = pLeaf->pNext; |
2428 sqlite3_free(pLeaf); | 2750 sqlite3_free(pLeaf); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2474 }else{ | 2796 }else{ |
2475 cell.iRowid = sqlite3_value_int64(azData[2]); | 2797 cell.iRowid = sqlite3_value_int64(azData[2]); |
2476 sqlite3_bind_int64(pRtree->pReadRowid, 1, cell.iRowid); | 2798 sqlite3_bind_int64(pRtree->pReadRowid, 1, cell.iRowid); |
2477 if( SQLITE_ROW==sqlite3_step(pRtree->pReadRowid) ){ | 2799 if( SQLITE_ROW==sqlite3_step(pRtree->pReadRowid) ){ |
2478 sqlite3_reset(pRtree->pReadRowid); | 2800 sqlite3_reset(pRtree->pReadRowid); |
2479 rc = SQLITE_CONSTRAINT; | 2801 rc = SQLITE_CONSTRAINT; |
2480 goto constraint; | 2802 goto constraint; |
2481 } | 2803 } |
2482 rc = sqlite3_reset(pRtree->pReadRowid); | 2804 rc = sqlite3_reset(pRtree->pReadRowid); |
2483 } | 2805 } |
| 2806 *pRowid = cell.iRowid; |
2484 | 2807 |
2485 if( rc==SQLITE_OK ){ | 2808 if( rc==SQLITE_OK ){ |
2486 rc = ChooseLeaf(pRtree, &cell, 0, &pLeaf); | 2809 rc = ChooseLeaf(pRtree, &cell, 0, &pLeaf); |
2487 } | 2810 } |
2488 if( rc==SQLITE_OK ){ | 2811 if( rc==SQLITE_OK ){ |
2489 int rc2; | 2812 int rc2; |
2490 pRtree->iReinsertHeight = -1; | 2813 pRtree->iReinsertHeight = -1; |
2491 rc = rtreeInsertCell(pRtree, pLeaf, &cell, 0); | 2814 rc = rtreeInsertCell(pRtree, pLeaf, &cell, 0); |
2492 rc2 = nodeRelease(pRtree, pLeaf); | 2815 rc2 = nodeRelease(pRtree, pLeaf); |
2493 if( rc==SQLITE_OK ){ | 2816 if( rc==SQLITE_OK ){ |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2611 }else{ | 2934 }else{ |
2612 rc = SQLITE_NOMEM; | 2935 rc = SQLITE_NOMEM; |
2613 } | 2936 } |
2614 sqlite3_free(zSql); | 2937 sqlite3_free(zSql); |
2615 } | 2938 } |
2616 | 2939 |
2617 return rc; | 2940 return rc; |
2618 } | 2941 } |
2619 | 2942 |
2620 /* | 2943 /* |
2621 ** This routine queries database handle db for the page-size used by | 2944 ** The second argument to this function contains the text of an SQL statement |
2622 ** database zDb. If successful, the page-size in bytes is written to | 2945 ** that returns a single integer value. The statement is compiled and executed |
2623 ** *piPageSize and SQLITE_OK returned. Otherwise, and an SQLite error | 2946 ** using database connection db. If successful, the integer value returned |
2624 ** code is returned. | 2947 ** is written to *piVal and SQLITE_OK returned. Otherwise, an SQLite error |
| 2948 ** code is returned and the value of *piVal after returning is not defined. |
2625 */ | 2949 */ |
2626 static int getPageSize(sqlite3 *db, const char *zDb, int *piPageSize){ | 2950 static int getIntFromStmt(sqlite3 *db, const char *zSql, int *piVal){ |
2627 int rc = SQLITE_NOMEM; | 2951 int rc = SQLITE_NOMEM; |
| 2952 if( zSql ){ |
| 2953 sqlite3_stmt *pStmt = 0; |
| 2954 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); |
| 2955 if( rc==SQLITE_OK ){ |
| 2956 if( SQLITE_ROW==sqlite3_step(pStmt) ){ |
| 2957 *piVal = sqlite3_column_int(pStmt, 0); |
| 2958 } |
| 2959 rc = sqlite3_finalize(pStmt); |
| 2960 } |
| 2961 } |
| 2962 return rc; |
| 2963 } |
| 2964 |
| 2965 /* |
| 2966 ** This function is called from within the xConnect() or xCreate() method to |
| 2967 ** determine the node-size used by the rtree table being created or connected |
| 2968 ** to. If successful, pRtree->iNodeSize is populated and SQLITE_OK returned. |
| 2969 ** Otherwise, an SQLite error code is returned. |
| 2970 ** |
| 2971 ** If this function is being called as part of an xConnect(), then the rtree |
| 2972 ** table already exists. In this case the node-size is determined by inspecting |
| 2973 ** the root node of the tree. |
| 2974 ** |
| 2975 ** Otherwise, for an xCreate(), use 64 bytes less than the database page-size. |
| 2976 ** This ensures that each node is stored on a single database page. If the |
| 2977 ** database page-size is so large that more than RTREE_MAXCELLS entries |
| 2978 ** would fit in a single node, use a smaller node-size. |
| 2979 */ |
| 2980 static int getNodeSize( |
| 2981 sqlite3 *db, /* Database handle */ |
| 2982 Rtree *pRtree, /* Rtree handle */ |
| 2983 int isCreate /* True for xCreate, false for xConnect */ |
| 2984 ){ |
| 2985 int rc; |
2628 char *zSql; | 2986 char *zSql; |
2629 sqlite3_stmt *pStmt = 0; | 2987 if( isCreate ){ |
2630 | 2988 int iPageSize; |
2631 zSql = sqlite3_mprintf("PRAGMA %Q.page_size", zDb); | 2989 zSql = sqlite3_mprintf("PRAGMA %Q.page_size", pRtree->zDb); |
2632 if( !zSql ){ | 2990 rc = getIntFromStmt(db, zSql, &iPageSize); |
2633 return SQLITE_NOMEM; | 2991 if( rc==SQLITE_OK ){ |
| 2992 pRtree->iNodeSize = iPageSize-64; |
| 2993 if( (4+pRtree->nBytesPerCell*RTREE_MAXCELLS)<pRtree->iNodeSize ){ |
| 2994 pRtree->iNodeSize = 4+pRtree->nBytesPerCell*RTREE_MAXCELLS; |
| 2995 } |
| 2996 } |
| 2997 }else{ |
| 2998 zSql = sqlite3_mprintf( |
| 2999 "SELECT length(data) FROM '%q'.'%q_node' WHERE nodeno = 1", |
| 3000 pRtree->zDb, pRtree->zName |
| 3001 ); |
| 3002 rc = getIntFromStmt(db, zSql, &pRtree->iNodeSize); |
2634 } | 3003 } |
2635 | 3004 |
2636 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); | |
2637 sqlite3_free(zSql); | 3005 sqlite3_free(zSql); |
2638 if( rc!=SQLITE_OK ){ | 3006 return rc; |
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 } | 3007 } |
2647 | 3008 |
2648 /* | 3009 /* |
2649 ** This function is the implementation of both the xConnect and xCreate | 3010 ** This function is the implementation of both the xConnect and xCreate |
2650 ** methods of the r-tree virtual table. | 3011 ** methods of the r-tree virtual table. |
2651 ** | 3012 ** |
2652 ** argv[0] -> module name | 3013 ** argv[0] -> module name |
2653 ** argv[1] -> database name | 3014 ** argv[1] -> database name |
2654 ** argv[2] -> table name | 3015 ** argv[2] -> table name |
2655 ** argv[...] -> column names... | 3016 ** argv[...] -> column names... |
2656 */ | 3017 */ |
2657 static int rtreeInit( | 3018 static int rtreeInit( |
2658 sqlite3 *db, /* Database connection */ | 3019 sqlite3 *db, /* Database connection */ |
2659 void *pAux, /* One of the RTREE_COORD_* constants */ | 3020 void *pAux, /* One of the RTREE_COORD_* constants */ |
2660 int argc, const char *const*argv, /* Parameters to CREATE TABLE statement */ | 3021 int argc, const char *const*argv, /* Parameters to CREATE TABLE statement */ |
2661 sqlite3_vtab **ppVtab, /* OUT: New virtual table */ | 3022 sqlite3_vtab **ppVtab, /* OUT: New virtual table */ |
2662 char **pzErr, /* OUT: Error message, if any */ | 3023 char **pzErr, /* OUT: Error message, if any */ |
2663 int isCreate /* True for xCreate, false for xConnect */ | 3024 int isCreate /* True for xCreate, false for xConnect */ |
2664 ){ | 3025 ){ |
2665 int rc = SQLITE_OK; | 3026 int rc = SQLITE_OK; |
2666 int iPageSize = 0; | |
2667 Rtree *pRtree; | 3027 Rtree *pRtree; |
2668 int nDb; /* Length of string argv[1] */ | 3028 int nDb; /* Length of string argv[1] */ |
2669 int nName; /* Length of string argv[2] */ | 3029 int nName; /* Length of string argv[2] */ |
2670 int eCoordType = (int)pAux; | 3030 int eCoordType = (pAux ? RTREE_COORD_INT32 : RTREE_COORD_REAL32); |
2671 | 3031 |
2672 const char *aErrMsg[] = { | 3032 const char *aErrMsg[] = { |
2673 0, /* 0 */ | 3033 0, /* 0 */ |
2674 "Wrong number of columns for an rtree table", /* 1 */ | 3034 "Wrong number of columns for an rtree table", /* 1 */ |
2675 "Too few columns for an rtree table", /* 2 */ | 3035 "Too few columns for an rtree table", /* 2 */ |
2676 "Too many columns for an rtree table" /* 3 */ | 3036 "Too many columns for an rtree table" /* 3 */ |
2677 }; | 3037 }; |
2678 | 3038 |
2679 int iErr = (argc<6) ? 2 : argc>(RTREE_MAX_DIMENSIONS*2+4) ? 3 : argc%2; | 3039 int iErr = (argc<6) ? 2 : argc>(RTREE_MAX_DIMENSIONS*2+4) ? 3 : argc%2; |
2680 if( aErrMsg[iErr] ){ | 3040 if( aErrMsg[iErr] ){ |
2681 *pzErr = sqlite3_mprintf("%s", aErrMsg[iErr]); | 3041 *pzErr = sqlite3_mprintf("%s", aErrMsg[iErr]); |
2682 return SQLITE_ERROR; | 3042 return SQLITE_ERROR; |
2683 } | 3043 } |
2684 | 3044 |
2685 rc = getPageSize(db, argv[1], &iPageSize); | |
2686 if( rc!=SQLITE_OK ){ | |
2687 return rc; | |
2688 } | |
2689 | |
2690 /* Allocate the sqlite3_vtab structure */ | 3045 /* Allocate the sqlite3_vtab structure */ |
2691 nDb = strlen(argv[1]); | 3046 nDb = strlen(argv[1]); |
2692 nName = strlen(argv[2]); | 3047 nName = strlen(argv[2]); |
2693 pRtree = (Rtree *)sqlite3_malloc(sizeof(Rtree)+nDb+nName+2); | 3048 pRtree = (Rtree *)sqlite3_malloc(sizeof(Rtree)+nDb+nName+2); |
2694 if( !pRtree ){ | 3049 if( !pRtree ){ |
2695 return SQLITE_NOMEM; | 3050 return SQLITE_NOMEM; |
2696 } | 3051 } |
2697 memset(pRtree, 0, sizeof(Rtree)+nDb+nName+2); | 3052 memset(pRtree, 0, sizeof(Rtree)+nDb+nName+2); |
2698 pRtree->nBusy = 1; | 3053 pRtree->nBusy = 1; |
2699 pRtree->base.pModule = &rtreeModule; | 3054 pRtree->base.pModule = &rtreeModule; |
2700 pRtree->zDb = (char *)&pRtree[1]; | 3055 pRtree->zDb = (char *)&pRtree[1]; |
2701 pRtree->zName = &pRtree->zDb[nDb+1]; | 3056 pRtree->zName = &pRtree->zDb[nDb+1]; |
2702 pRtree->nDim = (argc-4)/2; | 3057 pRtree->nDim = (argc-4)/2; |
2703 pRtree->nBytesPerCell = 8 + pRtree->nDim*4*2; | 3058 pRtree->nBytesPerCell = 8 + pRtree->nDim*4*2; |
2704 pRtree->eCoordType = eCoordType; | 3059 pRtree->eCoordType = eCoordType; |
2705 memcpy(pRtree->zDb, argv[1], nDb); | 3060 memcpy(pRtree->zDb, argv[1], nDb); |
2706 memcpy(pRtree->zName, argv[2], nName); | 3061 memcpy(pRtree->zName, argv[2], nName); |
2707 | 3062 |
2708 /* Figure out the node size to use. By default, use 64 bytes less than | 3063 /* Figure out the node size to use. */ |
2709 ** the database page-size. This ensures that each node is stored on | 3064 rc = getNodeSize(db, pRtree, isCreate); |
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 | 3065 |
2720 /* Create/Connect to the underlying relational database schema. If | 3066 /* Create/Connect to the underlying relational database schema. If |
2721 ** that is successful, call sqlite3_declare_vtab() to configure | 3067 ** that is successful, call sqlite3_declare_vtab() to configure |
2722 ** the r-tree table schema. | 3068 ** the r-tree table schema. |
2723 */ | 3069 */ |
2724 if( (rc = rtreeSqlInit(pRtree, db, argv[1], argv[2], isCreate)) ){ | 3070 if( rc==SQLITE_OK ){ |
2725 *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); | 3071 if( (rc = rtreeSqlInit(pRtree, db, argv[1], argv[2], isCreate)) ){ |
2726 }else{ | 3072 *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); |
2727 char *zSql = sqlite3_mprintf("CREATE TABLE x(%s", argv[3]); | 3073 }else{ |
2728 char *zTmp; | 3074 char *zSql = sqlite3_mprintf("CREATE TABLE x(%s", argv[3]); |
2729 int ii; | 3075 char *zTmp; |
2730 for(ii=4; zSql && ii<argc; ii++){ | 3076 int ii; |
2731 zTmp = zSql; | 3077 for(ii=4; zSql && ii<argc; ii++){ |
2732 zSql = sqlite3_mprintf("%s, %s", zTmp, argv[ii]); | 3078 zTmp = zSql; |
2733 sqlite3_free(zTmp); | 3079 zSql = sqlite3_mprintf("%s, %s", zTmp, argv[ii]); |
| 3080 sqlite3_free(zTmp); |
| 3081 } |
| 3082 if( zSql ){ |
| 3083 zTmp = zSql; |
| 3084 zSql = sqlite3_mprintf("%s);", zTmp); |
| 3085 sqlite3_free(zTmp); |
| 3086 } |
| 3087 if( !zSql ){ |
| 3088 rc = SQLITE_NOMEM; |
| 3089 }else if( SQLITE_OK!=(rc = sqlite3_declare_vtab(db, zSql)) ){ |
| 3090 *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); |
| 3091 } |
| 3092 sqlite3_free(zSql); |
2734 } | 3093 } |
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 } | 3094 } |
2747 | 3095 |
2748 if( rc==SQLITE_OK ){ | 3096 if( rc==SQLITE_OK ){ |
2749 *ppVtab = (sqlite3_vtab *)pRtree; | 3097 *ppVtab = (sqlite3_vtab *)pRtree; |
2750 }else{ | 3098 }else{ |
2751 rtreeRelease(pRtree); | 3099 rtreeRelease(pRtree); |
2752 } | 3100 } |
2753 return rc; | 3101 return rc; |
2754 } | 3102 } |
2755 | 3103 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2818 sqlite3_result_int(ctx, readInt16(zBlob)); | 3166 sqlite3_result_int(ctx, readInt16(zBlob)); |
2819 } | 3167 } |
2820 } | 3168 } |
2821 | 3169 |
2822 /* | 3170 /* |
2823 ** Register the r-tree module with database handle db. This creates the | 3171 ** Register the r-tree module with database handle db. This creates the |
2824 ** virtual table module "rtree" and the debugging/analysis scalar | 3172 ** virtual table module "rtree" and the debugging/analysis scalar |
2825 ** function "rtreenode". | 3173 ** function "rtreenode". |
2826 */ | 3174 */ |
2827 int sqlite3RtreeInit(sqlite3 *db){ | 3175 int sqlite3RtreeInit(sqlite3 *db){ |
2828 int rc = SQLITE_OK; | 3176 const int utf8 = SQLITE_UTF8; |
| 3177 int rc; |
2829 | 3178 |
2830 if( rc==SQLITE_OK ){ | 3179 rc = sqlite3_create_function(db, "rtreenode", 2, utf8, 0, rtreenode, 0, 0); |
2831 int utf8 = SQLITE_UTF8; | |
2832 rc = sqlite3_create_function(db, "rtreenode", 2, utf8, 0, rtreenode, 0, 0); | |
2833 } | |
2834 if( rc==SQLITE_OK ){ | 3180 if( rc==SQLITE_OK ){ |
2835 int utf8 = SQLITE_UTF8; | 3181 int utf8 = SQLITE_UTF8; |
2836 rc = sqlite3_create_function(db, "rtreedepth", 1, utf8, 0,rtreedepth, 0, 0); | 3182 rc = sqlite3_create_function(db, "rtreedepth", 1, utf8, 0,rtreedepth, 0, 0); |
2837 } | 3183 } |
2838 if( rc==SQLITE_OK ){ | 3184 if( rc==SQLITE_OK ){ |
2839 void *c = (void *)RTREE_COORD_REAL32; | 3185 void *c = (void *)RTREE_COORD_REAL32; |
2840 rc = sqlite3_create_module_v2(db, "rtree", &rtreeModule, c, 0); | 3186 rc = sqlite3_create_module_v2(db, "rtree", &rtreeModule, c, 0); |
2841 } | 3187 } |
2842 if( rc==SQLITE_OK ){ | 3188 if( rc==SQLITE_OK ){ |
2843 void *c = (void *)RTREE_COORD_INT32; | 3189 void *c = (void *)RTREE_COORD_INT32; |
2844 rc = sqlite3_create_module_v2(db, "rtree_i32", &rtreeModule, c, 0); | 3190 rc = sqlite3_create_module_v2(db, "rtree_i32", &rtreeModule, c, 0); |
2845 } | 3191 } |
2846 | 3192 |
2847 return rc; | 3193 return rc; |
2848 } | 3194 } |
2849 | 3195 |
| 3196 /* |
| 3197 ** A version of sqlite3_free() that can be used as a callback. This is used |
| 3198 ** in two places - as the destructor for the blob value returned by the |
| 3199 ** invocation of a geometry function, and as the destructor for the geometry |
| 3200 ** functions themselves. |
| 3201 */ |
| 3202 static void doSqlite3Free(void *p){ |
| 3203 sqlite3_free(p); |
| 3204 } |
| 3205 |
| 3206 /* |
| 3207 ** Each call to sqlite3_rtree_geometry_callback() creates an ordinary SQLite |
| 3208 ** scalar user function. This C function is the callback used for all such |
| 3209 ** registered SQL functions. |
| 3210 ** |
| 3211 ** The scalar user functions return a blob that is interpreted by r-tree |
| 3212 ** table MATCH operators. |
| 3213 */ |
| 3214 static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){ |
| 3215 RtreeGeomCallback *pGeomCtx = (RtreeGeomCallback *)sqlite3_user_data(ctx); |
| 3216 RtreeMatchArg *pBlob; |
| 3217 int nBlob; |
| 3218 |
| 3219 nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(double); |
| 3220 pBlob = (RtreeMatchArg *)sqlite3_malloc(nBlob); |
| 3221 if( !pBlob ){ |
| 3222 sqlite3_result_error_nomem(ctx); |
| 3223 }else{ |
| 3224 int i; |
| 3225 pBlob->magic = RTREE_GEOMETRY_MAGIC; |
| 3226 pBlob->xGeom = pGeomCtx->xGeom; |
| 3227 pBlob->pContext = pGeomCtx->pContext; |
| 3228 pBlob->nParam = nArg; |
| 3229 for(i=0; i<nArg; i++){ |
| 3230 pBlob->aParam[i] = sqlite3_value_double(aArg[i]); |
| 3231 } |
| 3232 sqlite3_result_blob(ctx, pBlob, nBlob, doSqlite3Free); |
| 3233 } |
| 3234 } |
| 3235 |
| 3236 /* |
| 3237 ** Register a new geometry function for use with the r-tree MATCH operator. |
| 3238 */ |
| 3239 int sqlite3_rtree_geometry_callback( |
| 3240 sqlite3 *db, |
| 3241 const char *zGeom, |
| 3242 int (*xGeom)(sqlite3_rtree_geometry *, int, double *, int *), |
| 3243 void *pContext |
| 3244 ){ |
| 3245 RtreeGeomCallback *pGeomCtx; /* Context object for new user-function */ |
| 3246 |
| 3247 /* Allocate and populate the context object. */ |
| 3248 pGeomCtx = (RtreeGeomCallback *)sqlite3_malloc(sizeof(RtreeGeomCallback)); |
| 3249 if( !pGeomCtx ) return SQLITE_NOMEM; |
| 3250 pGeomCtx->xGeom = xGeom; |
| 3251 pGeomCtx->pContext = pContext; |
| 3252 |
| 3253 /* Create the new user-function. Register a destructor function to delete |
| 3254 ** the context object when it is no longer required. */ |
| 3255 return sqlite3_create_function_v2(db, zGeom, -1, SQLITE_ANY, |
| 3256 (void *)pGeomCtx, geomCallback, 0, 0, doSqlite3Free |
| 3257 ); |
| 3258 } |
| 3259 |
2850 #if !SQLITE_CORE | 3260 #if !SQLITE_CORE |
2851 int sqlite3_extension_init( | 3261 int sqlite3_extension_init( |
2852 sqlite3 *db, | 3262 sqlite3 *db, |
2853 char **pzErrMsg, | 3263 char **pzErrMsg, |
2854 const sqlite3_api_routines *pApi | 3264 const sqlite3_api_routines *pApi |
2855 ){ | 3265 ){ |
2856 SQLITE_EXTENSION_INIT2(pApi) | 3266 SQLITE_EXTENSION_INIT2(pApi) |
2857 return sqlite3RtreeInit(db); | 3267 return sqlite3RtreeInit(db); |
2858 } | 3268 } |
2859 #endif | 3269 #endif |
2860 | 3270 |
2861 #endif | 3271 #endif |
OLD | NEW |