/ Check-in [ca7357e6]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Continuing work on the new custom query mechanism for r-tree.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | rtree-enhancements
Files: files | file ages | folders
SHA1: ca7357e66ca60f59477b1db000c2cdaeb8082ae1
User & Date: drh 2014-04-13 16:10:09
Context
2014-04-14
12:18
Remove over 300 lines of unused code, code that implemented the older Guttman insertion algorithms that are no longer used. check-in: 3ba5f295 user: drh tags: rtree-enhancements
2014-04-13
16:10
Continuing work on the new custom query mechanism for r-tree. check-in: ca7357e6 user: drh tags: rtree-enhancements
2014-04-12
17:44
Continuing clean-up of the R-Tree module in preparation for cutting in the new generalized query mechanism. check-in: 66c858f2 user: drh tags: rtree-enhancements
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/rtree/rtree.c.

   268    268   
   269    269   /*
   270    270   ** A search constraint.
   271    271   */
   272    272   struct RtreeConstraint {
   273    273     int iCoord;                     /* Index of constrained coordinate */
   274    274     int op;                         /* Constraining operation */
   275         -  RtreeDValue rValue;             /* Constraint value. */
   276         -  int (*xGeom)(sqlite3_rtree_geometry*, int, RtreeDValue*, int*);
   277         -  sqlite3_rtree_geometry *pGeom;  /* Constraint callback argument for a MATCH */
          275  +  union {
          276  +    RtreeDValue rValue;             /* Constraint value. */
          277  +    int (*xGeom)(sqlite3_rtree_geometry*,int,RtreeDValue*,int*);
          278  +    int (*xQueryFunc)(sqlite3_rtree_query_info*);
          279  +  } u;
          280  +  sqlite3_rtree_query_info *pGeom;  /* xGeom and xQueryFunc argument */
   278    281   };
   279    282   
   280    283   /* Possible values for RtreeConstraint.op */
   281    284   #define RTREE_EQ    0x41
   282    285   #define RTREE_LE    0x42
   283    286   #define RTREE_LT    0x43
   284    287   #define RTREE_GE    0x44
   285    288   #define RTREE_GT    0x45
   286         -#define RTREE_MATCH 0x46
          289  +#define RTREE_MATCH 0x46  /* Old-style sqlite3_rtree_geometry_callback() */
          290  +#define RTREE_QUERY 0x47  /* New-style sqlite3_rtree_query_callback() */
   287    291   
   288    292   /* 
   289    293   ** An rtree structure node.
   290    294   */
   291    295   struct RtreeNode {
   292    296     RtreeNode *pParent;         /* Parent node */
   293    297     i64 iNode;                  /* The node number */
................................................................................
   856    860   /*
   857    861   ** Free the RtreeCursor.aConstraint[] array and its contents.
   858    862   */
   859    863   static void freeCursorConstraints(RtreeCursor *pCsr){
   860    864     if( pCsr->aConstraint ){
   861    865       int i;                        /* Used to iterate through constraint array */
   862    866       for(i=0; i<pCsr->nConstraint; i++){
   863         -      sqlite3_rtree_geometry *pGeom = pCsr->aConstraint[i].pGeom;
          867  +      sqlite3_rtree_query_info *pGeom = pCsr->aConstraint[i].pGeom;
   864    868         if( pGeom ){
   865    869           if( pGeom->xDelUser ) pGeom->xDelUser(pGeom->pUser);
   866    870           sqlite3_free(pGeom);
   867    871         }
   868    872       }
   869    873       sqlite3_free(pCsr->aConstraint);
   870    874       pCsr->aConstraint = 0;
................................................................................
   911    915   
   912    916     assert( pConstraint->op==RTREE_MATCH );
   913    917     assert( pConstraint->pGeom );
   914    918   
   915    919     for(i=0; i<nCoord; i++){
   916    920       aCoord[i] = DCOORD(pCell->aCoord[i]);
   917    921     }
   918         -  return pConstraint->xGeom(pConstraint->pGeom, nCoord, aCoord, pbRes);
          922  +  return pConstraint->u.xGeom((sqlite3_rtree_geometry*)pConstraint->pGeom,
          923  +                              nCoord, aCoord, pbRes);
   919    924   }
   920    925   
   921    926   /* 
   922    927   ** Cursor pCursor currently points to a cell in a non-leaf page.
   923    928   ** Set *pbEof to true if the sub-tree headed by the cell is filtered
   924    929   ** (excluded) by the constraints in the pCursor->aConstraint[] 
   925    930   ** array, or false otherwise.
................................................................................
   941    946   
   942    947       assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE 
   943    948           || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_MATCH
   944    949       );
   945    950   
   946    951       switch( p->op ){
   947    952         case RTREE_LE: case RTREE_LT: 
   948         -        bRes = p->rValue<cell_min; 
          953  +        bRes = p->u.rValue<cell_min; 
   949    954           break;
   950    955   
   951    956         case RTREE_GE: case RTREE_GT: 
   952         -        bRes = p->rValue>cell_max; 
          957  +        bRes = p->u.rValue>cell_max; 
   953    958           break;
   954    959   
   955    960         case RTREE_EQ:
   956         -        bRes = (p->rValue>cell_max || p->rValue<cell_min);
          961  +        bRes = (p->u.rValue>cell_max || p->u.rValue<cell_min);
   957    962           break;
   958    963   
   959    964         default: {
   960    965           assert( p->op==RTREE_MATCH );
   961    966           rc = testRtreeGeom(pRtree, p, &cell, &bRes);
   962    967           bRes = !bRes;
   963    968           break;
................................................................................
   991    996       RtreeConstraint *p = &pCursor->aConstraint[ii];
   992    997       RtreeDValue coord = DCOORD(cell.aCoord[p->iCoord]);
   993    998       int res;
   994    999       assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE 
   995   1000           || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_MATCH
   996   1001       );
   997   1002       switch( p->op ){
   998         -      case RTREE_LE: res = (coord<=p->rValue); break;
   999         -      case RTREE_LT: res = (coord<p->rValue);  break;
  1000         -      case RTREE_GE: res = (coord>=p->rValue); break;
  1001         -      case RTREE_GT: res = (coord>p->rValue);  break;
  1002         -      case RTREE_EQ: res = (coord==p->rValue); break;
         1003  +      case RTREE_LE: res = (coord<=p->u.rValue); break;
         1004  +      case RTREE_LT: res = (coord<p->u.rValue);  break;
         1005  +      case RTREE_GE: res = (coord>=p->u.rValue); break;
         1006  +      case RTREE_GT: res = (coord>p->u.rValue);  break;
         1007  +      case RTREE_EQ: res = (coord==p->u.rValue); break;
  1003   1008         default: {
  1004   1009           int rc;
  1005   1010           assert( p->op==RTREE_MATCH );
  1006   1011           rc = testRtreeGeom(pRtree, p, &cell, &res);
  1007   1012           if( rc!=SQLITE_OK ){
  1008   1013             return rc;
  1009   1014           }
................................................................................
  1226   1231   ** This function is called to configure the RtreeConstraint object passed
  1227   1232   ** as the second argument for a MATCH constraint. The value passed as the
  1228   1233   ** first argument to this function is the right-hand operand to the MATCH
  1229   1234   ** operator.
  1230   1235   */
  1231   1236   static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){
  1232   1237     RtreeMatchArg *p;
  1233         -  sqlite3_rtree_geometry *pGeom;
         1238  +  sqlite3_rtree_query_info *pGeom;
  1234   1239     int nBlob;
  1235   1240   
  1236   1241     /* Check that value is actually a blob. */
  1237   1242     if( sqlite3_value_type(pValue)!=SQLITE_BLOB ) return SQLITE_ERROR;
  1238   1243   
  1239   1244     /* Check that the blob is roughly the right size. */
  1240   1245     nBlob = sqlite3_value_bytes(pValue);
  1241   1246     if( nBlob<(int)sizeof(RtreeMatchArg) 
  1242   1247      || ((nBlob-sizeof(RtreeMatchArg))%sizeof(RtreeDValue))!=0
  1243   1248     ){
  1244   1249       return SQLITE_ERROR;
  1245   1250     }
  1246   1251   
  1247         -  pGeom = (sqlite3_rtree_geometry *)sqlite3_malloc(
  1248         -      sizeof(sqlite3_rtree_geometry) + nBlob
  1249         -  );
         1252  +  pGeom = (sqlite3_rtree_query_info*)sqlite3_malloc( sizeof(*pGeom)+nBlob );
  1250   1253     if( !pGeom ) return SQLITE_NOMEM;
  1251         -  memset(pGeom, 0, sizeof(sqlite3_rtree_geometry));
  1252         -  p = (RtreeMatchArg *)&pGeom[1];
         1254  +  memset(pGeom, 0, sizeof(*pGeom));
         1255  +  p = (RtreeMatchArg*)&pGeom[1];
  1253   1256   
  1254   1257     memcpy(p, sqlite3_value_blob(pValue), nBlob);
  1255   1258     if( p->magic!=RTREE_GEOMETRY_MAGIC 
  1256   1259      || nBlob!=(int)(sizeof(RtreeMatchArg) + (p->nParam-1)*sizeof(RtreeDValue))
  1257   1260     ){
  1258   1261       sqlite3_free(pGeom);
  1259   1262       return SQLITE_ERROR;
  1260   1263     }
  1261   1264   
  1262   1265     pGeom->pContext = p->cb.pContext;
  1263   1266     pGeom->nParam = p->nParam;
  1264   1267     pGeom->aParam = p->aParam;
  1265   1268   
  1266         -  pCons->xGeom = p->cb.xGeom;
         1269  +  pCons->u.xGeom = p->cb.xGeom;
  1267   1270     pCons->pGeom = pGeom;
  1268   1271     return SQLITE_OK;
  1269   1272   }
  1270   1273   
  1271   1274   /* 
  1272   1275   ** Rtree virtual table module xFilter method.
  1273   1276   */
................................................................................
  1322   1325               */
  1323   1326               rc = deserializeGeometry(argv[ii], p);
  1324   1327               if( rc!=SQLITE_OK ){
  1325   1328                 break;
  1326   1329               }
  1327   1330             }else{
  1328   1331   #ifdef SQLITE_RTREE_INT_ONLY
  1329         -            p->rValue = sqlite3_value_int64(argv[ii]);
         1332  +            p->u.rValue = sqlite3_value_int64(argv[ii]);
  1330   1333   #else
  1331         -            p->rValue = sqlite3_value_double(argv[ii]);
         1334  +            p->u.rValue = sqlite3_value_double(argv[ii]);
  1332   1335   #endif
  1333   1336             }
  1334   1337           }
  1335   1338         }
  1336   1339       }
  1337   1340     
  1338   1341       if( rc==SQLITE_OK ){

Changes to ext/rtree/sqlite3rtree.h.

    73     73   );
    74     74   
    75     75   
    76     76   /*
    77     77   ** A pointer to a structure of the following type is passed as the 
    78     78   ** argument to scored geometry callback registered using
    79     79   ** sqlite3_rtree_query_callback().
           80  +**
           81  +** Note that the first 5 fields of this structure are identical to
           82  +** sqlite3_rtree_geometry.  This structure is a subclass of
           83  +** sqlite3_rtree_geometry.
    80     84   */
    81     85   struct sqlite3_rtree_query_info {
    82     86     void *pContext;                   /* pContext from when function registered */
    83     87     int nParam;                       /* Number of function parameters */
    84     88     sqlite3_rtree_dbl *aParam;        /* value of function parameters */
    85     89     void *pUser;                      /* callback can use this, if desired */
    86     90     void (*xDelUser)(void*);          /* function to free pUser */