mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-09 14:21:03 +03:00
Test versions of getVarint functions. The updates essentially utilize loop unrolling and some shifting/anding tricks to minimize the number of logical operations required. (CVS 5072)
FossilOrigin-Name: 682dc24dbe82d0326377e27c5ff97db3499873b0
This commit is contained in:
293
src/util.c
293
src/util.c
@@ -14,7 +14,7 @@
|
||||
** This file contains functions for allocating memory, comparing
|
||||
** strings, and stuff like that.
|
||||
**
|
||||
** $Id: util.c,v 1.224 2008/04/28 17:41:31 shane Exp $
|
||||
** $Id: util.c,v 1.225 2008/05/01 02:47:04 shane Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <stdarg.h>
|
||||
@@ -533,41 +533,158 @@ int sqlite3PutVarint32(unsigned char *p, u32 v){
|
||||
** Return the number of bytes read. The value is stored in *v.
|
||||
*/
|
||||
int sqlite3GetVarint(const unsigned char *p, u64 *v){
|
||||
u32 x;
|
||||
u64 x64;
|
||||
int n;
|
||||
unsigned char c;
|
||||
if( ((c = p[0]) & 0x80)==0 ){
|
||||
*v = c;
|
||||
u32 a,b,s;
|
||||
|
||||
a = *p;
|
||||
// a: p0 (unmasked)
|
||||
if (!(a&0x80))
|
||||
{
|
||||
*v = a;
|
||||
return 1;
|
||||
}
|
||||
x = c & 0x7f;
|
||||
if( ((c = p[1]) & 0x80)==0 ){
|
||||
*v = (x<<7) | c;
|
||||
|
||||
p++;
|
||||
b = *p;
|
||||
// b: p1 (unmasked)
|
||||
if (!(b&0x80))
|
||||
{
|
||||
a &= 0x7f;
|
||||
a = a<<7;
|
||||
a |= b;
|
||||
*v = a;
|
||||
return 2;
|
||||
}
|
||||
x = (x<<7) | (c&0x7f);
|
||||
if( ((c = p[2]) & 0x80)==0 ){
|
||||
*v = (x<<7) | c;
|
||||
|
||||
p++;
|
||||
a = a<<14;
|
||||
a |= *p;
|
||||
// a: p0<<14 | p2 (unmasked)
|
||||
if (!(a&0x80))
|
||||
{
|
||||
a &= (0x7f<<14)|(0x7f);
|
||||
b &= 0x7f;
|
||||
b = b<<7;
|
||||
a |= b;
|
||||
*v = a;
|
||||
return 3;
|
||||
}
|
||||
x = (x<<7) | (c&0x7f);
|
||||
if( ((c = p[3]) & 0x80)==0 ){
|
||||
*v = (x<<7) | c;
|
||||
|
||||
// CSE1 from below
|
||||
a &= (0x7f<<14)|(0x7f);
|
||||
p++;
|
||||
b = b<<14;
|
||||
b |= *p;
|
||||
// b: p1<<14 | p3 (unmasked)
|
||||
if (!(b&0x80))
|
||||
{
|
||||
b &= (0x7f<<14)|(0x7f);
|
||||
// moved CSE1 up
|
||||
// a &= (0x7f<<14)|(0x7f);
|
||||
a = a<<7;
|
||||
a |= b;
|
||||
*v = a;
|
||||
return 4;
|
||||
}
|
||||
x64 = (x<<7) | (c&0x7f);
|
||||
n = 4;
|
||||
do{
|
||||
c = p[n++];
|
||||
if( n==9 ){
|
||||
x64 = (x64<<8) | c;
|
||||
break;
|
||||
}
|
||||
x64 = (x64<<7) | (c&0x7f);
|
||||
}while( (c & 0x80)!=0 );
|
||||
*v = x64;
|
||||
return n;
|
||||
|
||||
// a: p0<<14 | p2 (masked)
|
||||
// b: p1<<14 | p3 (unmasked)
|
||||
// 1:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked)
|
||||
// moved CSE1 up
|
||||
// a &= (0x7f<<14)|(0x7f);
|
||||
b &= (0x7f<<14)|(0x7f);
|
||||
s = a;
|
||||
// s: p0<<14 | p2 (masked)
|
||||
|
||||
p++;
|
||||
a = a<<14;
|
||||
a |= *p;
|
||||
// a: p0<<28 | p2<<14 | p4 (unmasked)
|
||||
if (!(a&0x80))
|
||||
{
|
||||
// we can skip these cause they were (effectively) done above in calc'ing s
|
||||
// a &= (0x7f<<28)|(0x7f<<14)|(0x7f);
|
||||
// b &= (0x7f<<14)|(0x7f);
|
||||
b = b<<7;
|
||||
a |= b;
|
||||
s = s>>18;
|
||||
*v = ((u64)s)<<32 | a;
|
||||
return 5;
|
||||
}
|
||||
|
||||
// 2:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked)
|
||||
s = s<<7;
|
||||
s |= b;
|
||||
// s: p0<<21 | p1<<14 | p2<<7 | p3 (masked)
|
||||
|
||||
p++;
|
||||
b = b<<14;
|
||||
b |= *p;
|
||||
// b: p1<<28 | p3<<14 | p5 (unmasked)
|
||||
if (!(b&0x80))
|
||||
{
|
||||
// we can skip this cause it was (effectively) done above in calc'ing s
|
||||
// b &= (0x7f<<28)|(0x7f<<14)|(0x7f);
|
||||
a &= (0x7f<<14)|(0x7f);
|
||||
a = a<<7;
|
||||
a |= b;
|
||||
s = s>>18;
|
||||
*v = ((u64)s)<<32 | a;
|
||||
return 6;
|
||||
}
|
||||
|
||||
p++;
|
||||
a = a<<14;
|
||||
a |= *p;
|
||||
// a: p2<<28 | p4<<14 | p6 (unmasked)
|
||||
if (!(a&0x80))
|
||||
{
|
||||
a &= (0x7f<<28)|(0x7f<<14)|(0x7f);
|
||||
b &= (0x7f<<14)|(0x7f);
|
||||
b = b<<7;
|
||||
a |= b;
|
||||
s = s>>11;
|
||||
*v = ((u64)s)<<32 | a;
|
||||
return 7;
|
||||
}
|
||||
|
||||
// CSE2 from below
|
||||
a &= (0x7f<<14)|(0x7f);
|
||||
p++;
|
||||
b = b<<14;
|
||||
b |= *p;
|
||||
// b: p3<<28 | p5<<14 | p7 (unmasked)
|
||||
if (!(b&0x80))
|
||||
{
|
||||
b &= (0x7f<<28)|(0x7f<<14)|(0x7f);
|
||||
// moved CSE2 up
|
||||
// a &= (0x7f<<14)|(0x7f);
|
||||
a = a<<7;
|
||||
a |= b;
|
||||
s = s>>4;
|
||||
*v = ((u64)s)<<32 | a;
|
||||
return 8;
|
||||
}
|
||||
|
||||
p++;
|
||||
a = a<<15;
|
||||
a |= *p;
|
||||
// a: p4<<29 | p6<<15 | p8 (unmasked)
|
||||
|
||||
// moved CSE2 up
|
||||
// a &= (0x7f<<29)|(0x7f<<15)|(0xff);
|
||||
b &= (0x7f<<14)|(0x7f);
|
||||
b = b<<8;
|
||||
a |= b;
|
||||
|
||||
s = s<<4;
|
||||
b = p[-4];
|
||||
b &= 0x7f;
|
||||
b = b>>3;
|
||||
s |= b;
|
||||
|
||||
*v = ((u64)s)<<32 | a;
|
||||
|
||||
return 9;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -578,27 +695,117 @@ int sqlite3GetVarint(const unsigned char *p, u64 *v){
|
||||
** this function assumes the single-byte case has already been handled.
|
||||
*/
|
||||
int sqlite3GetVarint32(const unsigned char *p, u32 *v){
|
||||
u32 x;
|
||||
int n;
|
||||
unsigned char c;
|
||||
u32 a,b;
|
||||
|
||||
a = *p;
|
||||
// a: p0 (unmasked)
|
||||
#ifndef getVarint32
|
||||
if( ((signed char*)p)[0]>=0 ){
|
||||
*v = p[0];
|
||||
if (!(a&0x80))
|
||||
{
|
||||
*v = a;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
x = p[0] & 0x7f;
|
||||
if( ((signed char*)p)[1]>=0 ){
|
||||
*v = (x<<7) | p[1];
|
||||
|
||||
p++;
|
||||
b = *p;
|
||||
// b: p1 (unmasked)
|
||||
if (!(b&0x80))
|
||||
{
|
||||
a &= 0x7f;
|
||||
a = a<<7;
|
||||
*v = a | b;
|
||||
return 2;
|
||||
}
|
||||
x = (x<<7) | (p[1] & 0x7f);
|
||||
n = 2;
|
||||
do{
|
||||
x = (x<<7) | ((c = p[n++])&0x7f);
|
||||
}while( (c & 0x80)!=0 && n<9 );
|
||||
*v = x;
|
||||
return n;
|
||||
|
||||
p++;
|
||||
a = a<<14;
|
||||
a |= *p;
|
||||
// a: p0<<14 | p2 (unmasked)
|
||||
if (!(a&0x80))
|
||||
{
|
||||
a &= (0x7f<<14)|(0x7f);
|
||||
b &= 0x7f;
|
||||
b = b<<7;
|
||||
*v = a | b;
|
||||
return 3;
|
||||
}
|
||||
|
||||
p++;
|
||||
b = b<<14;
|
||||
b |= *p;
|
||||
// b: p1<<14 | p3 (unmasked)
|
||||
if (!(b&0x80))
|
||||
{
|
||||
b &= (0x7f<<14)|(0x7f);
|
||||
a &= (0x7f<<14)|(0x7f);
|
||||
a = a<<7;
|
||||
*v = a | b;
|
||||
return 4;
|
||||
}
|
||||
|
||||
p++;
|
||||
a = a<<14;
|
||||
a |= *p;
|
||||
// a: p0<<28 | p2<<14 | p4 (unmasked)
|
||||
if (!(a&0x80))
|
||||
{
|
||||
a &= (0x7f<<28)|(0x7f<<14)|(0x7f);
|
||||
b &= (0x7f<<28)|(0x7f<<14)|(0x7f);
|
||||
b = b<<7;
|
||||
*v = a | b;
|
||||
return 5;
|
||||
}
|
||||
|
||||
p++;
|
||||
b = b<<14;
|
||||
b |= *p;
|
||||
// b: p1<<28 | p3<<14 | p5 (unmasked)
|
||||
if (!(b&0x80))
|
||||
{
|
||||
b &= (0x7f<<28)|(0x7f<<14)|(0x7f);
|
||||
a &= (0x7f<<28)|(0x7f<<14)|(0x7f);
|
||||
a = a<<7;
|
||||
*v = a | b;
|
||||
return 6;
|
||||
}
|
||||
|
||||
p++;
|
||||
a = a<<14;
|
||||
a |= *p;
|
||||
// a: p2<<28 | p4<<14 | p6 (unmasked)
|
||||
if (!(a&0x80))
|
||||
{
|
||||
a &= (0x7f<<28)|(0x7f<<14)|(0x7f);
|
||||
b &= (0x7f<<28)|(0x7f<<14)|(0x7f);
|
||||
b = b<<7;
|
||||
*v = a | b;
|
||||
return 7;
|
||||
}
|
||||
|
||||
p++;
|
||||
b = b<<14;
|
||||
b |= *p;
|
||||
// b: p3<<28 | p5<<14 | p7 (unmasked)
|
||||
if (!(b&0x80))
|
||||
{
|
||||
b &= (0x7f<<28)|(0x7f<<14)|(0x7f);
|
||||
a &= (0x7f<<28)|(0x7f<<14)|(0x7f);
|
||||
a = a<<7;
|
||||
*v = a | b;
|
||||
return 8;
|
||||
}
|
||||
|
||||
p++;
|
||||
a = a<<14;
|
||||
a |= *p;
|
||||
// a: p4<<28 | p6<<14 | p8 (unmasked)
|
||||
|
||||
a &= (0x7f<<28)|(0x7f<<14)|(0x7f);
|
||||
b &= (0x7f<<28)|(0x7f<<14)|(0x7f);
|
||||
b = b<<7;
|
||||
*v = a | b;
|
||||
return 9;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user