diff options
author | drh <drh@noemail.net> | 2015-06-30 15:10:29 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2015-06-30 15:10:29 +0000 |
commit | da6d3e2117fd2ab1cbcc0f21ac5839d08d04344e (patch) | |
tree | fab3e1861926f343b3d81296e4a8fa6d14f684cd /src | |
parent | 3169906d061c60903ca654b5bdbc6355f7cee1e7 (diff) | |
parent | ad265296ffbaa5d238f3fd9c4e09398be92c3af1 (diff) | |
download | sqlite-da6d3e2117fd2ab1cbcc0f21ac5839d08d04344e.tar.gz sqlite-da6d3e2117fd2ab1cbcc0f21ac5839d08d04344e.zip |
Make use of built-in bswap32() and bswap16() functions in GCC/Clang for a
significant performance improvement there.
FossilOrigin-Name: 8bfcda3d10aec864d71d12a1248c37e4db6f8899
Diffstat (limited to 'src')
-rw-r--r-- | src/btree.c | 14 | ||||
-rw-r--r-- | src/btreeInt.h | 13 | ||||
-rw-r--r-- | src/sqliteInt.h | 7 | ||||
-rw-r--r-- | src/util.c | 17 |
4 files changed, 44 insertions, 7 deletions
diff --git a/src/btree.c b/src/btree.c index ef2a86152..fe2c067db 100644 --- a/src/btree.c +++ b/src/btree.c @@ -971,9 +971,9 @@ static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){ ** This routine works only for pages that do not contain overflow cells. */ #define findCell(P,I) \ - ((P)->aData + ((P)->maskPage & get2byte(&(P)->aCellIdx[2*(I)]))) + ((P)->aData + ((P)->maskPage & get2byteAligned(&(P)->aCellIdx[2*(I)]))) #define findCellPastPtr(P,I) \ - ((P)->aDataOfst + ((P)->maskPage & get2byte(&(P)->aCellIdx[2*(I)]))) + ((P)->aDataOfst + ((P)->maskPage & get2byteAligned(&(P)->aCellIdx[2*(I)]))) /* @@ -1754,7 +1754,7 @@ static int btreeInitPage(MemPage *pPage){ if( !pPage->leaf ) iCellLast--; for(i=0; i<pPage->nCell; i++){ - pc = get2byte(&data[cellOffset+i*2]); + pc = get2byteAligned(&data[cellOffset+i*2]); testcase( pc==iCellFirst ); testcase( pc==iCellLast ); if( pc<iCellFirst || pc>iCellLast ){ @@ -6625,7 +6625,7 @@ static int editPage( #ifdef SQLITE_DEBUG for(i=0; i<nNew && !CORRUPT_DB; i++){ u8 *pCell = pCArray->apCell[i+iNew]; - int iOff = get2byte(&pPg->aCellIdx[i*2]); + int iOff = get2byteAligned(&pPg->aCellIdx[i*2]); if( pCell>=aData && pCell<&aData[pPg->pBt->usableSize] ){ pCell = &pTmp[pCell - aData]; } @@ -7127,7 +7127,7 @@ static int balance_nonroot( memset(&b.szCell[b.nCell+limit], 0, sizeof(b.szCell[0])*pOld->nOverflow); limit = pOld->aiOvfl[0]; for(j=0; j<limit; j++){ - b.apCell[b.nCell] = aData + (maskPage & get2byte(piCell)); + b.apCell[b.nCell] = aData + (maskPage & get2byteAligned(piCell)); piCell += 2; b.nCell++; } @@ -7140,7 +7140,7 @@ static int balance_nonroot( piEnd = aData + pOld->cellOffset + 2*pOld->nCell; while( piCell<piEnd ){ assert( b.nCell<nMaxCells ); - b.apCell[b.nCell] = aData + (maskPage & get2byte(piCell)); + b.apCell[b.nCell] = aData + (maskPage & get2byteAligned(piCell)); piCell += 2; b.nCell++; } @@ -9105,7 +9105,7 @@ static int checkTreePage( /* EVIDENCE-OF: R-02776-14802 The cell pointer array consists of K 2-byte ** integer offsets to the cell contents. */ for(i=0; i<nCell; i++){ - int pc = get2byte(&data[cellStart+i*2]); + int pc = get2byteAligned(&data[cellStart+i*2]); u32 size = 65536; if( pc<=usableSize-4 ){ size = pPage->xCellSize(pPage, &data[pc]); diff --git a/src/btreeInt.h b/src/btreeInt.h index 92a4d4469..74117848a 100644 --- a/src/btreeInt.h +++ b/src/btreeInt.h @@ -691,3 +691,16 @@ struct IntegrityCk { #define put2byte(p,v) ((p)[0] = (u8)((v)>>8), (p)[1] = (u8)(v)) #define get4byte sqlite3Get4byte #define put4byte sqlite3Put4byte + +/* +** get2byteAligned(), unlike get2byte(), requires that its argument point to a +** two-byte aligned address. get2bytea() is only used for accessing the +** cell addresses in a btree header. +*/ +#if SQLITE_BYTEORDER==4321 +# define get2byteAligned(x) (*(u16*)(x)) +#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4008000 +# define get2byteAligned(x) __builtin_bswap16(*(u16*)(x)) +#else +# define get2byteAligned(x) ((x)[0]<<8 | (x)[1]) +#endif diff --git a/src/sqliteInt.h b/src/sqliteInt.h index aed6557cd..907434889 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -60,6 +60,13 @@ # define _LARGEFILE_SOURCE 1 #endif +/* What version of GCC is being used. 0 means GCC is not being used */ +#ifdef __GNUC__ +# define GCC_VERSION (__GNUC__*1000000+__GNUC_MINOR__*1000+__GNUC_PATCHLEVEL__) +#else +# define GCC_VERSION 0 +#endif + /* Needed for various definitions... */ #if defined(__GNUC__) && !defined(_GNU_SOURCE) # define _GNU_SOURCE diff --git a/src/util.c b/src/util.c index 8fdaf2678..4e029b0e0 100644 --- a/src/util.c +++ b/src/util.c @@ -1078,14 +1078,31 @@ int sqlite3VarintLen(u64 v){ ** Read or write a four-byte big-endian integer value. */ u32 sqlite3Get4byte(const u8 *p){ +#if SQLITE_BYTEORDER==4321 + u32 x; + memcpy(&x,p,4); + return x; +#elif SQLITE_BYTEORDER==1234 && defined(__GNUC__) + u32 x; + memcpy(&x,p,4); + return __builtin_bswap32(x); +#else testcase( p[0]&0x80 ); return ((unsigned)p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3]; +#endif } void sqlite3Put4byte(unsigned char *p, u32 v){ +#if SQLITE_BYTEORDER==4321 + memcpy(p,&v,4); +#elif SQLITE_BYTEORDER==1234 && defined(__GNUC__) + u32 x = __builtin_bswap32(v); + memcpy(p,&x,4); +#else p[0] = (u8)(v>>24); p[1] = (u8)(v>>16); p[2] = (u8)(v>>8); p[3] = (u8)v; +#endif } |