Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 ** 2015 May 30 | 2 ** 2016 Feb 29 |
| 3 ** | 3 ** |
| 4 ** The author disclaims copyright to this source code. In place of | 4 ** The author disclaims copyright to this source code. In place of |
| 5 ** a legal notice, here is a blessing: | 5 ** a legal notice, here is a blessing: |
| 6 ** | 6 ** |
| 7 ** May you do good and not evil. | 7 ** May you do good and not evil. |
| 8 ** May you find forgiveness for yourself and forgive others. | 8 ** May you find forgiveness for yourself and forgive others. |
| 9 ** May you share freely, never taking more than you give. | 9 ** May you share freely, never taking more than you give. |
|
Scott Hess - ex-Googler
2016/03/02 01:12:08
I'm hoping/intending to upstream this, so it has t
| |
| 10 ** | 10 ** |
| 11 ****************************************************************************** | 11 ****************************************************************************** |
| 12 ** | 12 ** |
| 13 ** Routines for varint serialization and deserialization. | 13 ** Copy of sqlite3Fts5GetVarint() from fts3_varint.c, which in turn is copied |
|
Scott Hess - ex-Googler
2016/03/02 01:12:08
fts5_varint.c, rather.
fts5_varint.c is the file
| |
| 14 ** from SQLite core. | |
| 14 */ | 15 */ |
| 15 | 16 |
| 17 #include <assert.h> | |
| 18 #include "sqlite3.h" | |
| 16 | 19 |
| 17 #include "fts5Int.h" | 20 /* Copied from fts3int.h. */ |
| 18 | 21 #ifndef SQLITE_AMALGAMATION |
| 19 /* | 22 typedef unsigned char u8; |
| 20 ** This is a copy of the sqlite3GetVarint32() routine from the SQLite core. | 23 typedef unsigned int u32; |
|
Scott Hess - ex-Googler
2016/03/02 01:12:08
fts5Int.h, rather. Didn't mess with these, becaus
| |
| 21 ** Except, this version does handle the single byte case that the core | 24 typedef sqlite3_uint64 u64; |
| 22 ** version depends on being handled before its function is called. | 25 #endif |
| 23 */ | |
| 24 int sqlite3Fts5GetVarint32(const unsigned char *p, u32 *v){ | |
| 25 u32 a,b; | |
| 26 | |
| 27 /* The 1-byte case. Overwhelmingly the most common. */ | |
| 28 a = *p; | |
| 29 /* a: p0 (unmasked) */ | |
| 30 if (!(a&0x80)) | |
| 31 { | |
| 32 /* Values between 0 and 127 */ | |
| 33 *v = a; | |
| 34 return 1; | |
| 35 } | |
| 36 | |
| 37 /* The 2-byte case */ | |
| 38 p++; | |
| 39 b = *p; | |
| 40 /* b: p1 (unmasked) */ | |
| 41 if (!(b&0x80)) | |
| 42 { | |
| 43 /* Values between 128 and 16383 */ | |
| 44 a &= 0x7f; | |
| 45 a = a<<7; | |
| 46 *v = a | b; | |
| 47 return 2; | |
| 48 } | |
| 49 | |
| 50 /* The 3-byte case */ | |
| 51 p++; | |
| 52 a = a<<14; | |
| 53 a |= *p; | |
| 54 /* a: p0<<14 | p2 (unmasked) */ | |
| 55 if (!(a&0x80)) | |
| 56 { | |
| 57 /* Values between 16384 and 2097151 */ | |
| 58 a &= (0x7f<<14)|(0x7f); | |
| 59 b &= 0x7f; | |
| 60 b = b<<7; | |
| 61 *v = a | b; | |
| 62 return 3; | |
| 63 } | |
| 64 | |
| 65 /* A 32-bit varint is used to store size information in btrees. | |
| 66 ** Objects are rarely larger than 2MiB limit of a 3-byte varint. | |
| 67 ** A 3-byte varint is sufficient, for example, to record the size | |
| 68 ** of a 1048569-byte BLOB or string. | |
| 69 ** | |
| 70 ** We only unroll the first 1-, 2-, and 3- byte cases. The very | |
| 71 ** rare larger cases can be handled by the slower 64-bit varint | |
| 72 ** routine. | |
| 73 */ | |
| 74 { | |
| 75 u64 v64; | |
| 76 u8 n; | |
| 77 p -= 2; | |
| 78 n = sqlite3Fts5GetVarint(p, &v64); | |
| 79 *v = (u32)v64; | |
| 80 assert( n>3 && n<=9 ); | |
| 81 return n; | |
| 82 } | |
| 83 } | |
| 84 | |
| 85 | 26 |
| 86 /* | 27 /* |
| 87 ** Bitmasks used by sqlite3GetVarint(). These precomputed constants | 28 ** Bitmasks used by sqlite3GetVarint(). These precomputed constants |
|
sdefresne
2016/03/08 15:42:36
nit: should this "sqlite3GetVarint()" be changed t
Scott Hess - ex-Googler
2016/03/08 18:37:36
Maybe? The SQLite people didn't adapt it for fts5
| |
| 88 ** are defined here rather than simply putting the constant expressions | 29 ** are defined here rather than simply putting the constant expressions |
| 89 ** inline in order to work around bugs in the RVT compiler. | 30 ** inline in order to work around bugs in the RVT compiler. |
| 90 ** | 31 ** |
| 91 ** SLOT_2_0 A mask for (0x7f<<14) | 0x7f | 32 ** SLOT_2_0 A mask for (0x7f<<14) | 0x7f |
| 92 ** | 33 ** |
| 93 ** SLOT_4_2_0 A mask for (0x7f<<28) | SLOT_2_0 | 34 ** SLOT_4_2_0 A mask for (0x7f<<28) | SLOT_2_0 |
| 94 */ | 35 */ |
| 95 #define SLOT_2_0 0x001fc07f | 36 #define SLOT_2_0 0x001fc07f |
| 96 #define SLOT_4_2_0 0xf01fc07f | 37 #define SLOT_4_2_0 0xf01fc07f |
| 97 | 38 |
| 98 /* | 39 /* |
| 99 ** Read a 64-bit variable-length integer from memory starting at p[0]. | 40 ** Read a 64-bit variable-length integer from memory starting at p[0]. |
| 100 ** Return the number of bytes read. The value is stored in *v. | 41 ** Return the number of bytes read. The value is stored in *v. |
| 101 */ | 42 */ |
| 102 u8 sqlite3Fts5GetVarint(const unsigned char *p, u64 *v){ | 43 u8 recoverGetVarint(const unsigned char *p, u64 *v){ |
| 103 u32 a,b,s; | 44 u32 a,b,s; |
| 104 | 45 |
| 105 a = *p; | 46 a = *p; |
| 106 /* a: p0 (unmasked) */ | 47 /* a: p0 (unmasked) */ |
| 107 if (!(a&0x80)) | 48 if (!(a&0x80)) |
| 108 { | 49 { |
| 109 *v = a; | 50 *v = a; |
| 110 return 1; | 51 return 1; |
| 111 } | 52 } |
| 112 | 53 |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 251 b = p[-4]; | 192 b = p[-4]; |
| 252 b &= 0x7f; | 193 b &= 0x7f; |
| 253 b = b>>3; | 194 b = b>>3; |
| 254 s |= b; | 195 s |= b; |
| 255 | 196 |
| 256 *v = ((u64)s)<<32 | a; | 197 *v = ((u64)s)<<32 | a; |
| 257 | 198 |
| 258 return 9; | 199 return 9; |
| 259 } | 200 } |
| 260 | 201 |
| 261 /* | |
| 262 ** The variable-length integer encoding is as follows: | |
| 263 ** | |
| 264 ** KEY: | |
| 265 ** A = 0xxxxxxx 7 bits of data and one flag bit | |
| 266 ** B = 1xxxxxxx 7 bits of data and one flag bit | |
| 267 ** C = xxxxxxxx 8 bits of data | |
| 268 ** | |
| 269 ** 7 bits - A | |
| 270 ** 14 bits - BA | |
| 271 ** 21 bits - BBA | |
| 272 ** 28 bits - BBBA | |
| 273 ** 35 bits - BBBBA | |
| 274 ** 42 bits - BBBBBA | |
| 275 ** 49 bits - BBBBBBA | |
| 276 ** 56 bits - BBBBBBBA | |
| 277 ** 64 bits - BBBBBBBBC | |
| 278 */ | |
| 279 | |
| 280 #ifdef SQLITE_NOINLINE | |
| 281 # define FTS5_NOINLINE SQLITE_NOINLINE | |
| 282 #else | |
| 283 # define FTS5_NOINLINE | |
| 284 #endif | |
| 285 | |
| 286 /* | |
| 287 ** Write a 64-bit variable-length integer to memory starting at p[0]. | |
| 288 ** The length of data write will be between 1 and 9 bytes. The number | |
| 289 ** of bytes written is returned. | |
| 290 ** | |
| 291 ** A variable-length integer consists of the lower 7 bits of each byte | |
| 292 ** for all bytes that have the 8th bit set and one byte with the 8th | |
| 293 ** bit clear. Except, if we get to the 9th byte, it stores the full | |
| 294 ** 8 bits and is the last byte. | |
| 295 */ | |
| 296 static int FTS5_NOINLINE fts5PutVarint64(unsigned char *p, u64 v){ | |
| 297 int i, j, n; | |
| 298 u8 buf[10]; | |
| 299 if( v & (((u64)0xff000000)<<32) ){ | |
| 300 p[8] = (u8)v; | |
| 301 v >>= 8; | |
| 302 for(i=7; i>=0; i--){ | |
| 303 p[i] = (u8)((v & 0x7f) | 0x80); | |
| 304 v >>= 7; | |
| 305 } | |
| 306 return 9; | |
| 307 } | |
| 308 n = 0; | |
| 309 do{ | |
| 310 buf[n++] = (u8)((v & 0x7f) | 0x80); | |
| 311 v >>= 7; | |
| 312 }while( v!=0 ); | |
| 313 buf[0] &= 0x7f; | |
| 314 assert( n<=9 ); | |
| 315 for(i=0, j=n-1; j>=0; j--, i++){ | |
| 316 p[i] = buf[j]; | |
| 317 } | |
| 318 return n; | |
| 319 } | |
| 320 | |
| 321 int sqlite3Fts5PutVarint(unsigned char *p, u64 v){ | |
| 322 if( v<=0x7f ){ | |
| 323 p[0] = v&0x7f; | |
| 324 return 1; | |
| 325 } | |
| 326 if( v<=0x3fff ){ | |
| 327 p[0] = ((v>>7)&0x7f)|0x80; | |
| 328 p[1] = v&0x7f; | |
| 329 return 2; | |
| 330 } | |
| 331 return fts5PutVarint64(p,v); | |
| 332 } | |
| 333 | |
| 334 | |
| 335 int sqlite3Fts5GetVarintLen(u32 iVal){ | |
| 336 if( iVal<(1 << 7 ) ) return 1; | |
| 337 if( iVal<(1 << 14) ) return 2; | |
| 338 if( iVal<(1 << 21) ) return 3; | |
| 339 if( iVal<(1 << 28) ) return 4; | |
| 340 return 5; | |
| 341 } | |
| 342 | |
| OLD | NEW |