mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
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
This commit is contained in:
@ -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.
|
||||
** 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(__x86) || defined(__x86_64) || defined(__arm__) || defined(_MSC_VER)
|
||||
#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
|
||||
);
|
||||
|
@ -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} {
|
||||
|
Reference in New Issue
Block a user