SQLite

Check-in [a929be5519]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Performance enhancement in sqlite3PutVarint().
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: a929be551924144c9bc7aab608404d59e479abb5
User & Date: drh 2014-08-22 18:48:25.634
Context
2014-08-22
20:35
Combine the pcacheAddToDirtyList() and pcacheRemoveFromDirtyList() routines into a single pcacheManageDirtyList() routine. The resulting binary code is slightly faster and a few bytes smaller. (check-in: 6bcf1af6a4 user: drh tags: trunk)
18:48
Performance enhancement in sqlite3PutVarint(). (check-in: a929be5519 user: drh tags: trunk)
18:00
Split the sqlite3Error() routine into sqlite3Error() and sqlite3ErrorWithMsg(), for a slight size reduction and performance increase. (check-in: cf561d1f0b user: drh tags: trunk)
Changes
Side-by-Side Diff Ignore Whitespace Patch
Changes to src/sqliteInt.h.
3303
3304
3305
3306
3307
3308
3309
3310

3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322

3323
3324

3325
3326
3327

3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341

3342
3343
3344
3345
3346
3347
3348
3303
3304
3305
3306
3307
3308
3309

3310


3311
3312

3313
3314
3315
3316
3317


3318


3319



3320








3321
3322
3323
3324
3325

3326
3327
3328
3329
3330
3331
3332
3333







-
+
-
-


-





-
-
+
-
-
+
-
-
-
+
-
-
-
-
-
-
-
-





-
+







LogEst sqlite3LogEstFromDouble(double);
#endif
u64 sqlite3LogEstToInt(LogEst);

/*
** Routines to read and write variable-length integers.  These used to
** be defined locally, but now we use the varint routines in the util.c
** file.  Code should use the MACRO forms below, as the Varint32 versions
** file.
** are coded to assume the single byte case is already handled (which 
** the MACRO form does).
*/
int sqlite3PutVarint(unsigned char*, u64);
int sqlite3PutVarint32(unsigned char*, u32);
u8 sqlite3GetVarint(const unsigned char *, u64 *);
u8 sqlite3GetVarint32(const unsigned char *, u32 *);
int sqlite3VarintLen(u64 v);

/*
** The header of a record consists of a sequence variable-length integers.
** These integers are almost always small and are encoded as a single byte.
** The common case is for a varint to be a single byte.  They following
** The following macros take advantage this fact to provide a fast encode
** and decode of the integers in a record header.  It is faster for the common
** macros handle the common case without a procedure call, but then call
** case where the integer is a single byte.  It is a little slower when the
** integer is two or more bytes.  But overall it is faster.
**
** the procedure for larger varints.
** The following expressions are equivalent:
**
**     x = sqlite3GetVarint32( A, &B );
**     x = sqlite3PutVarint32( A, B );
**
**     x = getVarint32( A, B );
**     x = putVarint32( A, B );
**
*/
#define getVarint32(A,B)  \
  (u8)((*(A)<(u8)0x80)?((B)=(u32)*(A)),1:sqlite3GetVarint32((A),(u32 *)&(B)))
#define putVarint32(A,B)  \
  (u8)(((u32)(B)<(u32)0x80)?(*(A)=(unsigned char)(B)),1:\
  sqlite3PutVarint32((A),(B)))
  sqlite3PutVarint((A),(B)))
#define getVarint    sqlite3GetVarint
#define putVarint    sqlite3PutVarint


const char *sqlite3IndexAffinityStr(Vdbe *, Index *);
void sqlite3TableAffinity(Vdbe*, Table*, int);
char sqlite3CompareAffinity(Expr *pExpr, char aff2);
Changes to src/util.c.
704
705
706
707
708
709
710
711

712
713
714
715
716
717
718
704
705
706
707
708
709
710

711
712
713
714
715
716
717
718







-
+







** of bytes written is returned.
**
** A variable-length integer consists of the lower 7 bits of each byte
** for all bytes that have the 8th bit set and one byte with the 8th
** bit clear.  Except, if we get to the 9th byte, it stores the full
** 8 bits and is the last byte.
*/
int sqlite3PutVarint(unsigned char *p, u64 v){
static int SQLITE_NOINLINE putVarint64(unsigned char *p, u64 v){
  int i, j, n;
  u8 buf[10];
  if( v & (((u64)0xff000000)<<32) ){
    p[8] = (u8)v;
    v >>= 8;
    for(i=7; i>=0; i--){
      p[i] = (u8)((v & 0x7f) | 0x80);
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744

745
746
747


748
749
750
751
752
753



754
755
756

757
758
759
760
761
762
763
728
729
730
731
732
733
734










735



736
737
738
739




740
741
742
743
744

745
746
747
748
749
750
751
752







-
-
-
-
-
-
-
-
-
-
+
-
-
-
+
+


-
-
-
-
+
+
+


-
+







  buf[0] &= 0x7f;
  assert( n<=9 );
  for(i=0, j=n-1; j>=0; j--, i++){
    p[i] = buf[j];
  }
  return n;
}

/*
** This routine is a faster version of sqlite3PutVarint() that only
** works for 32-bit positive integers and which is optimized for
** the common case of small integers.  A MACRO version, putVarint32,
** is provided which inlines the single-byte case.  All code should use
** the MACRO version as this function assumes the single-byte case has
** already been handled.
*/
int sqlite3PutVarint32(unsigned char *p, u32 v){
int sqlite3PutVarint(unsigned char *p, u64 v){
#ifndef putVarint32
  if( (v & ~0x7f)==0 ){
    p[0] = v;
  if( v<=0x7f ){
    p[0] = v&0x7f;
    return 1;
  }
#endif
  if( (v & ~0x3fff)==0 ){
    p[0] = (u8)((v>>7) | 0x80);
    p[1] = (u8)(v & 0x7f);
  if( v<=0x3fff ){
    p[0] = ((v>>7)&0x7f)|0x80;
    p[1] = v&0x7f;
    return 2;
  }
  return sqlite3PutVarint(p, v);
  return putVarint64(p,v);
}

/*
** Bitmasks used by sqlite3GetVarint().  These precomputed constants
** are defined here rather than simply putting the constant expressions
** inline in order to work around bugs in the RVT compiler.
**
Changes to src/vdbemem.c.
1126
1127
1128
1129
1130
1131
1132
1133

1134
1135
1136
1137
1138
1139
1140
1126
1127
1128
1129
1130
1131
1132

1133
1134
1135
1136
1137
1138
1139
1140







-
+








  nRet = 1 + nSerial + nVal;
  aRet = sqlite3DbMallocRaw(db, nRet);
  if( aRet==0 ){
    sqlite3_result_error_nomem(context);
  }else{
    aRet[0] = nSerial+1;
    sqlite3PutVarint(&aRet[1], iSerial);
    putVarint32(&aRet[1], iSerial);
    sqlite3VdbeSerialPut(&aRet[1+nSerial], argv[0], iSerial);
    sqlite3_result_blob(context, aRet, nRet, SQLITE_TRANSIENT);
    sqlite3DbFree(db, aRet);
  }
}

/*