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 |