1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-09 14:21:03 +03:00

New varint encoding gives a maximum varint length of 9 instead of 10. (CVS 1395)

FossilOrigin-Name: 61bdb53a363644074d01682fab8220078523676b
This commit is contained in:
drh
2004-05-18 15:57:42 +00:00
parent 10c0fa6a75
commit d8820e80fc
6 changed files with 98 additions and 36 deletions

View File

@@ -14,7 +14,7 @@
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.82 2004/05/14 16:50:06 drh Exp $
** $Id: util.c,v 1.83 2004/05/18 15:57:42 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
@@ -1139,6 +1139,25 @@ int sqlite3SafetyCheck(sqlite *db){
return 0;
}
/*
** The variable-length integer encoding is as follows:
**
** KEY:
** A = 0xxxxxxx 7 bits of data and one flag bit
** B = 1xxxxxxx 7 bits of data and one flag bit
** C = xxxxxxxx 8 bits of data
**
** 7 bits - A
** 14 bits - BA
** 21 bits - BBA
** 28 bits - BBBA
** 35 bits - BBBBA
** 42 bits - BBBBBA
** 49 bits - BBBBBBA
** 56 bits - BBBBBBBA
** 64 bits - BBBBBBBBC
*/
/*
** Write a 64-bit variable-length integer to memory starting at p[0].
** The length of data write will be between 1 and 9 bytes. The number
@@ -1146,17 +1165,28 @@ int sqlite3SafetyCheck(sqlite *db){
**
** 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.
** 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){
int i, j, n;
u8 buf[10];
if( v & 0xff00000000000000 ){
p[8] = v;
v >>= 8;
for(i=7; i>=0; i--){
p[i] = (v & 0x7f) | 0x80;
v >>= 7;
}
return 9;
}
n = 0;
do{
buf[n++] = (v & 0x7f) | 0x80;
v >>= 7;
}while( v!=0 );
buf[0] &= 0x7f;
assert( n<=9 );
for(i=0, j=n-1; j>=0; j--, i++){
p[i] = buf[j];
}
@@ -1199,6 +1229,10 @@ int sqlite3GetVarint(const unsigned char *p, u64 *v){
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;
@@ -1213,7 +1247,7 @@ int sqlite3GetVarint32(const unsigned char *p, u32 *v){
int n = 1;
unsigned char c = p[0];
u32 x = c & 0x7f;
while( (c & 0x80)!=0 ){
while( (c & 0x80)!=0 && n<9 ){
c = p[n++];
x = (x<<7) | (c & 0x7f);
}
@@ -1230,6 +1264,6 @@ int sqlite3VarintLen(u64 v){
do{
i++;
v >>= 7;
}while( v!=0 );
}while( v!=0 && i<9 );
return i;
}