modernc.org/cc@v1.0.1/v2/testdata/_sqlite/ext/fts5/fts5_varint.c (about) 1 /* 2 ** 2015 May 30 3 ** 4 ** The author disclaims copyright to this source code. In place of 5 ** a legal notice, here is a blessing: 6 ** 7 ** May you do good and not evil. 8 ** May you find forgiveness for yourself and forgive others. 9 ** May you share freely, never taking more than you give. 10 ** 11 ****************************************************************************** 12 ** 13 ** Routines for varint serialization and deserialization. 14 */ 15 16 17 #include "fts5Int.h" 18 19 /* 20 ** This is a copy of the sqlite3GetVarint32() routine from the SQLite core. 21 ** Except, this version does handle the single byte case that the core 22 ** version depends on being handled before its function is called. 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 86 /* 87 ** Bitmasks used by sqlite3GetVarint(). These precomputed constants 88 ** are defined here rather than simply putting the constant expressions 89 ** inline in order to work around bugs in the RVT compiler. 90 ** 91 ** SLOT_2_0 A mask for (0x7f<<14) | 0x7f 92 ** 93 ** SLOT_4_2_0 A mask for (0x7f<<28) | SLOT_2_0 94 */ 95 #define SLOT_2_0 0x001fc07f 96 #define SLOT_4_2_0 0xf01fc07f 97 98 /* 99 ** 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. 101 */ 102 u8 sqlite3Fts5GetVarint(const unsigned char *p, u64 *v){ 103 u32 a,b,s; 104 105 a = *p; 106 /* a: p0 (unmasked) */ 107 if (!(a&0x80)) 108 { 109 *v = a; 110 return 1; 111 } 112 113 p++; 114 b = *p; 115 /* b: p1 (unmasked) */ 116 if (!(b&0x80)) 117 { 118 a &= 0x7f; 119 a = a<<7; 120 a |= b; 121 *v = a; 122 return 2; 123 } 124 125 /* Verify that constants are precomputed correctly */ 126 assert( SLOT_2_0 == ((0x7f<<14) | (0x7f)) ); 127 assert( SLOT_4_2_0 == ((0xfU<<28) | (0x7f<<14) | (0x7f)) ); 128 129 p++; 130 a = a<<14; 131 a |= *p; 132 /* a: p0<<14 | p2 (unmasked) */ 133 if (!(a&0x80)) 134 { 135 a &= SLOT_2_0; 136 b &= 0x7f; 137 b = b<<7; 138 a |= b; 139 *v = a; 140 return 3; 141 } 142 143 /* CSE1 from below */ 144 a &= SLOT_2_0; 145 p++; 146 b = b<<14; 147 b |= *p; 148 /* b: p1<<14 | p3 (unmasked) */ 149 if (!(b&0x80)) 150 { 151 b &= SLOT_2_0; 152 /* moved CSE1 up */ 153 /* a &= (0x7f<<14)|(0x7f); */ 154 a = a<<7; 155 a |= b; 156 *v = a; 157 return 4; 158 } 159 160 /* a: p0<<14 | p2 (masked) */ 161 /* b: p1<<14 | p3 (unmasked) */ 162 /* 1:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */ 163 /* moved CSE1 up */ 164 /* a &= (0x7f<<14)|(0x7f); */ 165 b &= SLOT_2_0; 166 s = a; 167 /* s: p0<<14 | p2 (masked) */ 168 169 p++; 170 a = a<<14; 171 a |= *p; 172 /* a: p0<<28 | p2<<14 | p4 (unmasked) */ 173 if (!(a&0x80)) 174 { 175 /* we can skip these cause they were (effectively) done above in calc'ing s */ 176 /* a &= (0x7f<<28)|(0x7f<<14)|(0x7f); */ 177 /* b &= (0x7f<<14)|(0x7f); */ 178 b = b<<7; 179 a |= b; 180 s = s>>18; 181 *v = ((u64)s)<<32 | a; 182 return 5; 183 } 184 185 /* 2:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */ 186 s = s<<7; 187 s |= b; 188 /* s: p0<<21 | p1<<14 | p2<<7 | p3 (masked) */ 189 190 p++; 191 b = b<<14; 192 b |= *p; 193 /* b: p1<<28 | p3<<14 | p5 (unmasked) */ 194 if (!(b&0x80)) 195 { 196 /* we can skip this cause it was (effectively) done above in calc'ing s */ 197 /* b &= (0x7f<<28)|(0x7f<<14)|(0x7f); */ 198 a &= SLOT_2_0; 199 a = a<<7; 200 a |= b; 201 s = s>>18; 202 *v = ((u64)s)<<32 | a; 203 return 6; 204 } 205 206 p++; 207 a = a<<14; 208 a |= *p; 209 /* a: p2<<28 | p4<<14 | p6 (unmasked) */ 210 if (!(a&0x80)) 211 { 212 a &= SLOT_4_2_0; 213 b &= SLOT_2_0; 214 b = b<<7; 215 a |= b; 216 s = s>>11; 217 *v = ((u64)s)<<32 | a; 218 return 7; 219 } 220 221 /* CSE2 from below */ 222 a &= SLOT_2_0; 223 p++; 224 b = b<<14; 225 b |= *p; 226 /* b: p3<<28 | p5<<14 | p7 (unmasked) */ 227 if (!(b&0x80)) 228 { 229 b &= SLOT_4_2_0; 230 /* moved CSE2 up */ 231 /* a &= (0x7f<<14)|(0x7f); */ 232 a = a<<7; 233 a |= b; 234 s = s>>4; 235 *v = ((u64)s)<<32 | a; 236 return 8; 237 } 238 239 p++; 240 a = a<<15; 241 a |= *p; 242 /* a: p4<<29 | p6<<15 | p8 (unmasked) */ 243 244 /* moved CSE2 up */ 245 /* a &= (0x7f<<29)|(0x7f<<15)|(0xff); */ 246 b &= SLOT_2_0; 247 b = b<<8; 248 a |= b; 249 250 s = s<<4; 251 b = p[-4]; 252 b &= 0x7f; 253 b = b>>3; 254 s |= b; 255 256 *v = ((u64)s)<<32 | a; 257 258 return 9; 259 } 260 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 0 337 if( iVal<(1 << 7 ) ) return 1; 338 #endif 339 assert( iVal>=(1 << 7) ); 340 if( iVal<(1 << 14) ) return 2; 341 if( iVal<(1 << 21) ) return 3; 342 if( iVal<(1 << 28) ) return 4; 343 return 5; 344 } 345