From: drh Date: Fri, 18 Apr 2014 01:37:08 +0000 (+0000) Subject: Further improvements to the RTREE_DECODE_COORD() method, to take advantage X-Git-Tag: version-3.13.0~148^2~145^2~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ec7c03a08ba8fa274c38dca3d00c83ea0b518286;p=thirdparty%2Fsqlite.git Further improvements to the RTREE_DECODE_COORD() method, to take advantage of known processor byte orders when available. This makes the code 3% faster, according to valgrind. Also add test cases to make sure the on-disk representation is correct. FossilOrigin-Name: 6f3e94f4b1b403cd7bfc5e8e0ffbd61b5174d3a4 --- diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 620c158288..bcaa4d635a 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -904,16 +904,21 @@ static int rtreeEof(sqlite3_vtab_cursor *cur){ /* ** Convert raw bits from the on-disk RTree record into a coordinate value. -** The on-disk format is big-endian and needs to be converted for little-endian -** platforms. The on-disk record stores integer coordinates if eInt is true -** and it stores 32-bit floating point records if eInt is false. a[] is the four -** bytes of the on-disk record to be decoded. Store the results in "r". +** The on-disk format is big-endian and needs to be converted for little- +** endian platforms. The on-disk record stores integer coordinates if +** eInt is true and it stores 32-bit floating point records if eInt is +** false. a[] is the four bytes of the on-disk record to be decoded. +** Store the results in "r". ** -** The first version of this macro is fast on x86, x86_64 and ARM, all of which -** are little-endian. The second version of this macro is cross-platform but -** takes twice as long, according to valgrind on linux x64. -*/ -#if defined(__x86) || defined(__x86_64) || defined(__arm__) || defined(_MSC_VER) +** There are three versions of this macro, one each for little-endian and +** big-endian processors and a third generic implementation. The endian- +** specific implementations are much faster and are preferred if the +** processor endianness is known at compile-time. The SQLITE_BYTEORDER +** macro is part of sqliteInt.h and hence the endian-specific +** implementation will only be used if this module is compiled as part +** of the amalgamation. +*/ +#if defined(SQLITE_BYTEORDER) && SQLITE_BYTEORDER==1234 #define RTREE_DECODE_COORD(eInt, a, r) { \ RtreeCoord c; /* Coordinate decoded */ \ memcpy(&c.u,a,4); \ @@ -921,6 +926,12 @@ static int rtreeEof(sqlite3_vtab_cursor *cur){ ((c.u&0xff)<<24)|((c.u&0xff00)<<8); \ r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ } +#elif defined(SQLITE_BYTEORDER) && SQLITE_BYTEORDER==4321 +#define RTREE_DECODE_COORD(eInt, a, r) { \ + RtreeCoord c; /* Coordinate decoded */ \ + memcpy(&c.u,a,4); \ + r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ +} #else #define RTREE_DECODE_COORD(eInt, a, r) { \ RtreeCoord c; /* Coordinate decoded */ \ @@ -929,7 +940,6 @@ static int rtreeEof(sqlite3_vtab_cursor *cur){ r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ } #endif - /* ** Check the RTree node or entry given by pCellData and p against the MATCH @@ -2242,7 +2252,8 @@ static int SplitNode( memset(pLeft->zData, 0, pRtree->iNodeSize); memset(pRight->zData, 0, pRtree->iNodeSize); - rc = splitNodeStartree(pRtree, aCell, nCell, pLeft, pRight,&leftbbox,&rightbbox); + rc = splitNodeStartree(pRtree, aCell, nCell, pLeft, pRight, + &leftbbox, &rightbbox); if( rc!=SQLITE_OK ){ goto splitnode_out; } @@ -3003,7 +3014,8 @@ static int rtreeSqlInit( char *zCreate = sqlite3_mprintf( "CREATE TABLE \"%w\".\"%w_node\"(nodeno INTEGER PRIMARY KEY, data BLOB);" "CREATE TABLE \"%w\".\"%w_rowid\"(rowid INTEGER PRIMARY KEY, nodeno INTEGER);" -"CREATE TABLE \"%w\".\"%w_parent\"(nodeno INTEGER PRIMARY KEY, parentnode INTEGER);" +"CREATE TABLE \"%w\".\"%w_parent\"(nodeno INTEGER PRIMARY KEY," + " parentnode INTEGER);" "INSERT INTO '%q'.'%q_node' VALUES(1, zeroblob(%d))", zDb, zPrefix, zDb, zPrefix, zDb, zPrefix, zDb, zPrefix, pRtree->iNodeSize ); diff --git a/ext/rtree/rtree1.test b/ext/rtree/rtree1.test index 275b13264f..9de5362781 100644 --- a/ext/rtree/rtree1.test +++ b/ext/rtree/rtree1.test @@ -120,12 +120,13 @@ proc execsql_intout {sql} { # Test that it is possible to open an existing database that contains # r-tree tables. # -do_test rtree-1.4.1 { - execsql { - CREATE VIRTUAL TABLE t1 USING rtree(ii, x1, x2); - INSERT INTO t1 VALUES(1, 5.0, 10.0); - INSERT INTO t1 VALUES(2, 15.0, 20.0); - } +do_execsql_test rtree-1.4.1a { + CREATE VIRTUAL TABLE t1 USING rtree(ii, x1, x2); + INSERT INTO t1 VALUES(1, 5.0, 10.0); + SELECT substr(hex(data),1,40) FROM t1_node; +} {00000001000000000000000140A0000041200000} +do_execsql_test rtree-1.4.1b { + INSERT INTO t1 VALUES(2, 15.0, 20.0); } {} do_test rtree-1.4.2 { db close @@ -435,16 +436,18 @@ do_test rtree-11.2 { # Test on-conflict clause handling. # db_delete_and_reopen -do_execsql_test 12.0 { +do_execsql_test 12.0.1 { CREATE VIRTUAL TABLE t1 USING rtree_i32(idx, x1, x2, y1, y2); INSERT INTO t1 VALUES(1, 1, 2, 3, 4); + SELECT substr(hex(data),1,56) FROM t1_node; +} {00000001000000000000000100000001000000020000000300000004} +do_execsql_test 12.0.2 { INSERT INTO t1 VALUES(2, 2, 3, 4, 5); INSERT INTO t1 VALUES(3, 3, 4, 5, 6); CREATE TABLE source(idx, x1, x2, y1, y2); INSERT INTO source VALUES(5, 8, 8, 8, 8); INSERT INTO source VALUES(2, 7, 7, 7, 7); - } db_save_and_close foreach {tn sql_template testdata} { diff --git a/manifest b/manifest index 967e3767a3..760724c749 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\slatest\schanges\sfrom\ssessions. -D 2014-04-18T01:14:46.009 +C Further\simprovements\sto\sthe\sRTREE_DECODE_COORD()\smethod,\sto\stake\sadvantage\nof\sknown\sprocessor\sbyte\sorders\swhen\savailable.\s\sThis\smakes\sthe\scode\s3%\sfaster,\naccording\sto\svalgrind.\s\sAlso\sadd\stest\scases\sto\smake\ssure\sthe\son-disk\nrepresentation\sis\scorrect. +D 2014-04-18T01:37:08.946 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e4ee6d36cdf6136aee0158675a3b24dd3bf31a5a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -120,9 +120,9 @@ F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 5cf5ae21ca1742be863f025ce64e4262fc6def4c +F ext/rtree/rtree.c b8357523ca0aa01ec8efffdec0868909e3744257 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e -F ext/rtree/rtree1.test cf679265ecafff494a768ac9c2f43a70915a6290 +F ext/rtree/rtree1.test e2da4aaa426918d27122d1a1066c6ecf8409a514 F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba F ext/rtree/rtree3.test a494da55c30ee0bc9b01a91c80c81b387b22d2dc F ext/rtree/rtree4.test c8fe384f60ebd49540a5fecc990041bf452eb6e0 @@ -1177,7 +1177,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 444084fd620fc3f45cfb87b83f532d76bd2744e7 95e77efe076ab421bd246119c47dba5dacf9d087 -R e9845f4b2c71a18e1d378888de7ae7a2 +P d9eef5b03c7c4bb69c11eda41152ee81aed1cac7 +R fd5f15a432e8499b9e125ee6ec5ed14e U drh -Z 0c4fc380d884463ecab3c74420a85e5e +Z 4e8eac956a9a7b7e58efbf89636dab07 diff --git a/manifest.uuid b/manifest.uuid index 2112ab381a..ddcb25049d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d9eef5b03c7c4bb69c11eda41152ee81aed1cac7 \ No newline at end of file +6f3e94f4b1b403cd7bfc5e8e0ffbd61b5174d3a4 \ No newline at end of file