]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
More test cases with very long priority queues.
authordrh <drh@noemail.net>
Thu, 17 Apr 2014 15:34:58 +0000 (15:34 +0000)
committerdrh <drh@noemail.net>
Thu, 17 Apr 2014 15:34:58 +0000 (15:34 +0000)
FossilOrigin-Name: 71692aa97c78676f0ba80eaeec0ad9ac225f4427

ext/rtree/rtreeE.test
manifest
manifest.uuid
src/test_rtree.c

index 14f5c332ca586a97c85681e485453aef6e688b60..bc97943dcb3d6d772e5ec1336066736e11ad70b9 100644 (file)
@@ -27,46 +27,93 @@ register_circle_geom db
 
 do_execsql_test rtreeE-1.1 {
   PRAGMA page_size=512;
-  CREATE VIRTUAL TABLE rt2 USING rtree(id,x0,x1,y0,y1);
+  CREATE VIRTUAL TABLE rt1 USING rtree(id,x0,x1,y0,y1);
   
   /* A tight pattern of small boxes near 0,0 */
   WITH RECURSIVE
     x(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM x WHERE x<4),
     y(y) AS (VALUES(0) UNION ALL SELECT y+1 FROM y WHERE y<4)
-  INSERT INTO rt2 SELECT x+5*y, x, x+2, y, y+2 FROM x, y;
+  INSERT INTO rt1 SELECT x+5*y, x, x+2, y, y+2 FROM x, y;
 
   /* A looser pattern of small boxes near 100, 0 */
   WITH RECURSIVE
     x(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM x WHERE x<4),
     y(y) AS (VALUES(0) UNION ALL SELECT y+1 FROM y WHERE y<4)
-  INSERT INTO rt2 SELECT 100+x+5*y, x*3+100, x*3+102, y*3, y*3+2 FROM x, y;
+  INSERT INTO rt1 SELECT 100+x+5*y, x*3+100, x*3+102, y*3, y*3+2 FROM x, y;
 
   /* A looser pattern of larger boxes near 0, 200 */
   WITH RECURSIVE
     x(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM x WHERE x<4),
     y(y) AS (VALUES(0) UNION ALL SELECT y+1 FROM y WHERE y<4)
-  INSERT INTO rt2 SELECT 200+x+5*y, x*7, x*7+15, y*7+200, y*7+215 FROM x, y;
+  INSERT INTO rt1 SELECT 200+x+5*y, x*7, x*7+15, y*7+200, y*7+215 FROM x, y;
 } {}
 
-if 0 {
 # Queries against each of the three clusters */
 do_execsql_test rtreeE-1.1 {
-  SELECT id FROM rt2 WHERE id MATCH Qcircle(0.0, 0.0, 50.0) ORDER BY id;
+  SELECT id FROM rt1 WHERE id MATCH Qcircle(0.0, 0.0, 50.0, 3) ORDER BY id;
 } {0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24}
 do_execsql_test rtreeE-1.2 {
-  SELECT id FROM rt2 WHERE id MATCH Qcircle(100.0, 0.0, 50.0) ORDER BY id;
+  SELECT id FROM rt1 WHERE id MATCH Qcircle(100.0, 0.0, 50.0, 3) ORDER BY id;
 } {100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124}
 do_execsql_test rtreeE-1.3 {
-  SELECT id FROM rt2 WHERE id MATCH Qcircle(0.0, 200.0, 50.0) ORDER BY id;
+  SELECT id FROM rt1 WHERE id MATCH Qcircle(0.0, 200.0, 50.0, 3) ORDER BY id;
 } {200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224}
-}
 
 # The Qcircle geometry function gives a lower score to larger leaf-nodes.
 # This causes the 200s to sort before the 100s and the 0s to sort before
 # last.
 #
 do_execsql_test rtreeE-1.4 {
-  SELECT id FROM rt2 WHERE id MATCH Qcircle(0,0,1000) AND id%100==0
+  SELECT id FROM rt1 WHERE id MATCH Qcircle(0,0,1000,3) AND id%100==0
 } {200 100 0}
 
+# Construct a large 2-D RTree with thousands of random entries.
+#
+do_test rtreeE-2.1 {
+  db eval {
+    CREATE TABLE t2(id,x0,x1,y0,y1);
+    CREATE VIRTUAL TABLE rt2 USING rtree(id,x0,x1,y0,y1);
+    BEGIN;
+  }
+  expr srand(0)
+  for {set i 1} {$i<=10000} {incr i} {
+    set dx [expr {int(rand()*40)+1}]
+    set dy [expr {int(rand()*40)+1}]
+    set x0 [expr {int(rand()*(10000 - $dx))}]
+    set x1 [expr {$x0+$dx}]
+    set y0 [expr {int(rand()*(10000 - $dy))}]
+    set y1 [expr {$y0+$dy}]
+    set id [expr {$i+10000}]
+    db eval {INSERT INTO t2 VALUES($id,$x0,$x1,$y0,$y1)}
+  }
+  db eval {
+    INSERT INTO rt2 SELECT * FROM t2;
+    COMMIT;
+  }
+} {}
+
+for {set i 1} {$i<=200} {incr i} {
+  set dx [expr {int(rand()*100)}]
+  set dy [expr {int(rand()*100)}]
+  set x0 [expr {int(rand()*(10000 - $dx))}]
+  set x1 [expr {$x0+$dx}]
+  set y0 [expr {int(rand()*(10000 - $dy))}]
+  set y1 [expr {$y0+$dy}]
+  set ans [db eval {SELECT id FROM t2 WHERE x1>=$x0 AND x0<=$x1 AND y1>=$y0 AND y0<=$y1 ORDER BY id}]
+  do_execsql_test rtreeE-2.2.$i {
+    SELECT id FROM rt2 WHERE id MATCH breadthfirstsearch($x0,$x1,$y0,$y1) ORDER BY id
+  } $ans
+}
+
+# Run query that have very deep priority queues
+#
+set ans [db eval {SELECT id FROM t2 WHERE x1>=0 AND x0<=5000 AND y1>=0 AND y0<=5000 ORDER BY id}]
+do_execsql_test rtreeE-2.3 {
+  SELECT id FROM rt2 WHERE id MATCH breadthfirstsearch(0,5000,0,5000) ORDER BY id
+} $ans
+set ans [db eval {SELECT id FROM t2 WHERE x1>=0 AND x0<=10000 AND y1>=0 AND y0<=10000 ORDER BY id}]
+do_execsql_test rtreeE-2.4 {
+  SELECT id FROM rt2 WHERE id MATCH breadthfirstsearch(0,10000,0,10000) ORDER BY id
+} $ans
+
 finish_test
index 63a2d6b9ce493e72568da37fa0cbab2961c216df..6eb3fbb2651f6d220c4b9333a46373b22fa7c912 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Test\scases\sand\sbug\sfixes\sfor\sthe\ssqlite3_rtree_query_callback()\nmechanism.
-D 2014-04-17T14:52:20.025
+C More\stest\scases\swith\svery\slong\spriority\squeues.
+D 2014-04-17T15:34:58.372
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in e4ee6d36cdf6136aee0158675a3b24dd3bf31a5a
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -135,7 +135,7 @@ F ext/rtree/rtreeA.test ace05e729a36e342d40cf94e9efc7b4723d9dcdf
 F ext/rtree/rtreeB.test c85f9ce78766c4e68b8b89fbf2979ee9cfa82b4e
 F ext/rtree/rtreeC.test df158dcc81f1a43ce7eef361af03c48ec91f1e06
 F ext/rtree/rtreeD.test 636630357638f5983701550b37f0f5867130d2ca
-F ext/rtree/rtreeE.test c8c951df54fd556d30eb621ecc2acd8771970a5e
+F ext/rtree/rtreeE.test 0878fd6bce3a62ac980e6f67ba14cc86c8f4f2b3
 F ext/rtree/rtree_perf.tcl 6c18c1f23cd48e0f948930c98dfdd37dfccb5195
 F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea
 F ext/rtree/sqlite3rtree.h 488cf8834d2012b913d33683157d3cf5f1327a69
@@ -275,7 +275,7 @@ F src/test_osinst.c 90a845c8183013d80eccb1f29e8805608516edba
 F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00
 F src/test_quota.c 30c64f0ef84734f2231a686df41ed882b0c59bc0
 F src/test_quota.h 8761e463b25e75ebc078bd67d70e39b9c817a0cb
-F src/test_rtree.c 636d2a5bc9ded2fa1df4e7d4c575eb0d3f13b334
+F src/test_rtree.c 38cdb28581d07503c9135ef73692ec8192b876b0
 F src/test_schema.c cd12a2223c3a394f4d07bb93bdf6d344c5c121b6
 F src/test_server.c a2615049954cbb9cfb4a62e18e2f0616e4dc38fe
 F src/test_sqllog.c c1c1bbedbcaf82b93d83e4f9dd990e62476a680e
@@ -1176,7 +1176,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
-P 32a13870175a1dd1d33af3572dde09ff607a04b6
-R 1f38906450e19fda5c27a4543b70f18c
+P 1ccaaed6b516ec2ce953c1b31025a82ba76d00e7
+R 449eb9a5ce303ca34184a4306bd9d328
 U drh
-Z 26a5b86beaa061e155488cf6e80f8d30
+Z 39039e877d4cb95ab625ec95bd5cc650
index 07ccb102680fda0cd98a16b58f8217de7ccecb99..f923c4ba43c5cf6eba7f8363948395ea024b4649 100644 (file)
@@ -1 +1 @@
-1ccaaed6b516ec2ce953c1b31025a82ba76d00e7
\ No newline at end of file
+71692aa97c78676f0ba80eaeec0ad9ac225f4427
\ No newline at end of file
index c1951a896b24d5b0a5641fc5a41502061b6dd5ac..51e991949c36dceaa521ea5fceef983b942eeb96 100644 (file)
@@ -36,6 +36,7 @@ struct Circle {
   double centery;
   double radius;
   double mxArea;
+  int eScoreType;
 };
 
 /*
@@ -175,10 +176,10 @@ static int circle_query_func(sqlite3_rtree_query_info *p){
     ** Return an error if the table does not have exactly 2 dimensions. */
     if( p->nCoord!=4 ) return SQLITE_ERROR;
 
-    /* Test that the correct number of parameters (3) have been supplied,
+    /* Test that the correct number of parameters (4) have been supplied,
     ** and that the parameters are in range (that the radius of the circle 
     ** radius is greater than zero). */
-    if( p->nParam!=3 || p->aParam[2]<0.0 ) return SQLITE_ERROR;
+    if( p->nParam!=4 || p->aParam[2]<0.0 ) return SQLITE_ERROR;
 
     /* Allocate a structure to cache parameter data in. Return SQLITE_NOMEM
     ** if the allocation fails. */
@@ -193,6 +194,7 @@ static int circle_query_func(sqlite3_rtree_query_info *p){
     pCircle->centerx = p->aParam[0];
     pCircle->centery = p->aParam[1];
     pCircle->radius = p->aParam[2];
+    pCircle->eScoreType = (int)p->aParam[3];
 
     /* Define two bounding box regions. The first, aBox[0], extends to
     ** infinity in the X dimension. It covers the same range of the Y dimension
@@ -247,11 +249,21 @@ static int circle_query_func(sqlite3_rtree_query_info *p){
     }
   }
 
-  if( p->iLevel==2 ){
-    p->rScore = 1.0 - (xmax-xmin)*(ymax-ymin)/pCircle->mxArea;
-    if( p->rScore<0.01 ) p->rScore = 0.01;
+  if( pCircle->eScoreType==1 ){
+    /* Depth first search */
+    p->rScore = p->iLevel;
+  }else if( pCircle->eScoreType==2 ){
+    /* Breadth first search */
+    p->rScore = 100 - p->iLevel;
   }else{
-    p->rScore = 0.0;
+    /* Depth-first search, except sort the leaf nodes by area with
+    ** the largest area first */
+    if( p->iLevel==2 ){
+      p->rScore = 1.0 - (xmax-xmin)*(ymax-ymin)/pCircle->mxArea;
+      if( p->rScore<0.01 ) p->rScore = 0.01;
+    }else{
+      p->rScore = 0.0;
+    }
   }
   if( nWithin==0 ){
     p->eWithin = NOT_WITHIN;
@@ -262,6 +274,39 @@ static int circle_query_func(sqlite3_rtree_query_info *p){
   }
   return SQLITE_OK;
 }
+/*
+** Implementation of "breadthfirstsearch" r-tree geometry callback using the 
+** 2nd-generation interface that allows scoring.
+**
+**     ... WHERE id MATCH breadthfirstsearch($x0,$x1,$y0,$y1) ...
+**
+** It returns all entries whose bounding boxes overlap with $x0,$x1,$y0,$y1.
+*/
+static int bfs_query_func(sqlite3_rtree_query_info *p){
+  double x0,x1,y0,y1;        /* Dimensions of box being tested */
+  double bx0,bx1,by0,by1;    /* Boundary of the query function */
+
+  if( p->nParam!=4 ) return SQLITE_ERROR;
+  x0 = p->aCoord[0];
+  x1 = p->aCoord[1];
+  y0 = p->aCoord[2];
+  y1 = p->aCoord[3];
+  bx0 = p->aParam[0];
+  bx1 = p->aParam[1];
+  by0 = p->aParam[2];
+  by1 = p->aParam[3];
+  p->rScore = 100 - p->iLevel;
+  if( p->eParentWithin==FULLY_WITHIN ){
+    p->eWithin = FULLY_WITHIN;
+  }else if( x0>=bx0 && x1<=bx1 && y0>=by0 && y1<=by1 ){
+    p->eWithin = FULLY_WITHIN;
+  }else if( x1>=bx0 && x0<=bx1 && y1>=by0 && y0<=by1 ){
+    p->eWithin = PARTLY_WITHIN;
+  }else{
+    p->eWithin = NOT_WITHIN;
+  }
+  return SQLITE_OK;
+}
 
 /* END of implementation of "circle" geometry callback.
 **************************************************************************
@@ -402,6 +447,10 @@ static int register_circle_geom(
     rc = sqlite3_rtree_query_callback(db, "Qcircle",
                                       circle_query_func, 0, 0);
   }
+  if( rc==SQLITE_OK ){
+    rc = sqlite3_rtree_query_callback(db, "breadthfirstsearch",
+                                      bfs_query_func, 0, 0);
+  }
   Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_STATIC);
 #endif
   return TCL_OK;