1f5e7bb51Sdrh /* 2f5e7bb51Sdrh ** 2008 February 16 3f5e7bb51Sdrh ** 4f5e7bb51Sdrh ** The author disclaims copyright to this source code. In place of 5f5e7bb51Sdrh ** a legal notice, here is a blessing: 6f5e7bb51Sdrh ** 7f5e7bb51Sdrh ** May you do good and not evil. 8f5e7bb51Sdrh ** May you find forgiveness for yourself and forgive others. 9f5e7bb51Sdrh ** May you share freely, never taking more than you give. 10f5e7bb51Sdrh ** 11f5e7bb51Sdrh ************************************************************************* 12f5e7bb51Sdrh ** This file implements an object that represents a fixed-length 13f5e7bb51Sdrh ** bitmap. Bits are numbered starting with 1. 14f5e7bb51Sdrh ** 15dfe88eceSdrh ** A bitmap is used to record which pages of a database file have been 16dfe88eceSdrh ** journalled during a transaction, or which pages have the "dont-write" 17dfe88eceSdrh ** property. Usually only a few pages are meet either condition. 18dfe88eceSdrh ** So the bitmap is usually sparse and has low cardinality. 19f5e7bb51Sdrh ** But sometimes (for example when during a DROP of a large table) most 20dfe88eceSdrh ** or all of the pages in a database can get journalled. In those cases, 21dfe88eceSdrh ** the bitmap becomes dense with high cardinality. The algorithm needs 22dfe88eceSdrh ** to handle both cases well. 23f5e7bb51Sdrh ** 24f5e7bb51Sdrh ** The size of the bitmap is fixed when the object is created. 25f5e7bb51Sdrh ** 26f5e7bb51Sdrh ** All bits are clear when the bitmap is created. Individual bits 27f5e7bb51Sdrh ** may be set or cleared one at a time. 28f5e7bb51Sdrh ** 29f5e7bb51Sdrh ** Test operations are about 100 times more common that set operations. 30f5e7bb51Sdrh ** Clear operations are exceedingly rare. There are usually between 31f5e7bb51Sdrh ** 5 and 500 set operations per Bitvec object, though the number of sets can 32f5e7bb51Sdrh ** sometimes grow into tens of thousands or larger. The size of the 33f5e7bb51Sdrh ** Bitvec object is the number of pages in the database file at the 34f5e7bb51Sdrh ** start of a transaction, and is thus usually less than a few thousand, 35f5e7bb51Sdrh ** but can be as large as 2 billion for a really big database. 36f5e7bb51Sdrh */ 37f5e7bb51Sdrh #include "sqliteInt.h" 38f5e7bb51Sdrh 391feb7dd3Sdrh /* Size of the Bitvec structure in bytes. */ 40f6171e9bSdrh #define BITVEC_SZ 512 411feb7dd3Sdrh 42dda5b68cSmlcreech /* Round the union size down to the nearest pointer boundary, since that's how 43dda5b68cSmlcreech ** it will be aligned within the Bitvec struct. */ 441feb7dd3Sdrh #define BITVEC_USIZE (((BITVEC_SZ-(3*sizeof(u32)))/sizeof(Bitvec*))*sizeof(Bitvec*)) 451feb7dd3Sdrh 461feb7dd3Sdrh /* Type of the array "element" for the bitmap representation. 471feb7dd3Sdrh ** Should be a power of 2, and ideally, evenly divide into BITVEC_USIZE. 481feb7dd3Sdrh ** Setting this to the "natural word" size of your CPU may improve 491feb7dd3Sdrh ** performance. */ 501feb7dd3Sdrh #define BITVEC_TELEM u8 511feb7dd3Sdrh /* Size, in bits, of the bitmap element. */ 521feb7dd3Sdrh #define BITVEC_SZELEM 8 531feb7dd3Sdrh /* Number of elements in a bitmap array. */ 541feb7dd3Sdrh #define BITVEC_NELEM (BITVEC_USIZE/sizeof(BITVEC_TELEM)) 551feb7dd3Sdrh /* Number of bits in the bitmap array. */ 561feb7dd3Sdrh #define BITVEC_NBIT (BITVEC_NELEM*BITVEC_SZELEM) 571feb7dd3Sdrh 581feb7dd3Sdrh /* Number of u32 values in hash table. */ 591feb7dd3Sdrh #define BITVEC_NINT (BITVEC_USIZE/sizeof(u32)) 601feb7dd3Sdrh /* Maximum number of entries in hash table before 611feb7dd3Sdrh ** sub-dividing and re-hashing. */ 62f5e7bb51Sdrh #define BITVEC_MXHASH (BITVEC_NINT/2) 631feb7dd3Sdrh /* Hashing function for the aHash representation. 641feb7dd3Sdrh ** Empirical testing showed that the *37 multiplier 651feb7dd3Sdrh ** (an arbitrary prime)in the hash function provided 661feb7dd3Sdrh ** no fewer collisions than the no-op *1. */ 671feb7dd3Sdrh #define BITVEC_HASH(X) (((X)*1)%BITVEC_NINT) 681feb7dd3Sdrh 69dda5b68cSmlcreech #define BITVEC_NPTR (BITVEC_USIZE/sizeof(Bitvec *)) 70f5e7bb51Sdrh 71f5e7bb51Sdrh 72f5e7bb51Sdrh /* 73f5e7bb51Sdrh ** A bitmap is an instance of the following structure. 74f5e7bb51Sdrh ** 7548864df9Smistachkin ** This bitmap records the existence of zero or more bits 76f5e7bb51Sdrh ** with values between 1 and iSize, inclusive. 77f5e7bb51Sdrh ** 78f5e7bb51Sdrh ** There are three possible representations of the bitmap. 79f5e7bb51Sdrh ** If iSize<=BITVEC_NBIT, then Bitvec.u.aBitmap[] is a straight 80f5e7bb51Sdrh ** bitmap. The least significant bit is bit 1. 81f5e7bb51Sdrh ** 82f5e7bb51Sdrh ** If iSize>BITVEC_NBIT and iDivisor==0 then Bitvec.u.aHash[] is 83f5e7bb51Sdrh ** a hash table that will hold up to BITVEC_MXHASH distinct values. 84f5e7bb51Sdrh ** 85f5e7bb51Sdrh ** Otherwise, the value i is redirected into one of BITVEC_NPTR 86f5e7bb51Sdrh ** sub-bitmaps pointed to by Bitvec.u.apSub[]. Each subbitmap 87f5e7bb51Sdrh ** handles up to iDivisor separate values of i. apSub[0] holds 88f5e7bb51Sdrh ** values between 1 and iDivisor. apSub[1] holds values between 89f5e7bb51Sdrh ** iDivisor+1 and 2*iDivisor. apSub[N] holds values between 90f5e7bb51Sdrh ** N*iDivisor+1 and (N+1)*iDivisor. Each subbitmap is normalized 91f5e7bb51Sdrh ** to hold deal with values between 1 and iDivisor. 92f5e7bb51Sdrh */ 93f5e7bb51Sdrh struct Bitvec { 941feb7dd3Sdrh u32 iSize; /* Maximum bit index. Max iSize is 4,294,967,296. */ 9564f798ddSdrh u32 nSet; /* Number of bits that are set - only valid for aHash 9664f798ddSdrh ** element. Max is BITVEC_NINT. For BITVEC_SZ of 512, 9764f798ddSdrh ** this would be 125. */ 981feb7dd3Sdrh u32 iDivisor; /* Number of bits handled by each apSub[] entry. */ 991feb7dd3Sdrh /* Should >=0 for apSub element. */ 1001feb7dd3Sdrh /* Max iDivisor is max(u32) / BITVEC_NPTR + 1. */ 1011feb7dd3Sdrh /* For a BITVEC_SZ of 512, this would be 34,359,739. */ 102f5e7bb51Sdrh union { 1031feb7dd3Sdrh BITVEC_TELEM aBitmap[BITVEC_NELEM]; /* Bitmap representation */ 104f5e7bb51Sdrh u32 aHash[BITVEC_NINT]; /* Hash table representation */ 105f5e7bb51Sdrh Bitvec *apSub[BITVEC_NPTR]; /* Recursive representation */ 106f5e7bb51Sdrh } u; 107f5e7bb51Sdrh }; 108f5e7bb51Sdrh 109f5e7bb51Sdrh /* 110f5e7bb51Sdrh ** Create a new bitmap object able to handle bits between 0 and iSize, 111f5e7bb51Sdrh ** inclusive. Return a pointer to the new object. Return NULL if 112f5e7bb51Sdrh ** malloc fails. 113f5e7bb51Sdrh */ 114f5e7bb51Sdrh Bitvec *sqlite3BitvecCreate(u32 iSize){ 115f5e7bb51Sdrh Bitvec *p; 116f5e7bb51Sdrh assert( sizeof(*p)==BITVEC_SZ ); 117f5e7bb51Sdrh p = sqlite3MallocZero( sizeof(*p) ); 118f5e7bb51Sdrh if( p ){ 119f5e7bb51Sdrh p->iSize = iSize; 120f5e7bb51Sdrh } 121f5e7bb51Sdrh return p; 122f5e7bb51Sdrh } 123f5e7bb51Sdrh 124f5e7bb51Sdrh /* 125f5e7bb51Sdrh ** Check to see if the i-th bit is set. Return true or false. 126f5e7bb51Sdrh ** If p is NULL (if the bitmap has not been created) or if 127f5e7bb51Sdrh ** i is out of range, then return false. 128f5e7bb51Sdrh */ 129f5e7bb51Sdrh int sqlite3BitvecTest(Bitvec *p, u32 i){ 130f5e7bb51Sdrh if( p==0 ) return 0; 1313088d59eSdrh if( i>p->iSize || i==0 ) return 0; 132f5e7bb51Sdrh i--; 1331feb7dd3Sdrh while( p->iDivisor ){ 1341feb7dd3Sdrh u32 bin = i/p->iDivisor; 1351feb7dd3Sdrh i = i%p->iDivisor; 1361feb7dd3Sdrh p = p->u.apSub[bin]; 1371feb7dd3Sdrh if (!p) { 1381feb7dd3Sdrh return 0; 139f5e7bb51Sdrh } 1401feb7dd3Sdrh } 1411feb7dd3Sdrh if( p->iSize<=BITVEC_NBIT ){ 1421feb7dd3Sdrh return (p->u.aBitmap[i/BITVEC_SZELEM] & (1<<(i&(BITVEC_SZELEM-1))))!=0; 143f5e7bb51Sdrh } else{ 1441feb7dd3Sdrh u32 h = BITVEC_HASH(i++); 145f5e7bb51Sdrh while( p->u.aHash[h] ){ 146f5e7bb51Sdrh if( p->u.aHash[h]==i ) return 1; 1477ee27b07Sdrh h = (h+1) % BITVEC_NINT; 148f5e7bb51Sdrh } 149f5e7bb51Sdrh return 0; 150f5e7bb51Sdrh } 151f5e7bb51Sdrh } 152f5e7bb51Sdrh 153f5e7bb51Sdrh /* 154f5e7bb51Sdrh ** Set the i-th bit. Return 0 on success and an error code if 155f5e7bb51Sdrh ** anything goes wrong. 156dfe88eceSdrh ** 157dfe88eceSdrh ** This routine might cause sub-bitmaps to be allocated. Failing 158dfe88eceSdrh ** to get the memory needed to hold the sub-bitmap is the only 159dfe88eceSdrh ** that can go wrong with an insert, assuming p and i are valid. 160dfe88eceSdrh ** 161dfe88eceSdrh ** The calling function must ensure that p is a valid Bitvec object 162dfe88eceSdrh ** and that the value for "i" is within range of the Bitvec object. 163dfe88eceSdrh ** Otherwise the behavior is undefined. 164f5e7bb51Sdrh */ 165f5e7bb51Sdrh int sqlite3BitvecSet(Bitvec *p, u32 i){ 166f5e7bb51Sdrh u32 h; 1676aac11dcSdrh if( p==0 ) return SQLITE_OK; 1683088d59eSdrh assert( i>0 ); 169c5d0bd90Sdrh assert( i<=p->iSize ); 170f5e7bb51Sdrh i--; 1711feb7dd3Sdrh while((p->iSize > BITVEC_NBIT) && p->iDivisor) { 1721feb7dd3Sdrh u32 bin = i/p->iDivisor; 1731feb7dd3Sdrh i = i%p->iDivisor; 174f5e7bb51Sdrh if( p->u.apSub[bin]==0 ){ 175f5e7bb51Sdrh p->u.apSub[bin] = sqlite3BitvecCreate( p->iDivisor ); 176f5e7bb51Sdrh if( p->u.apSub[bin]==0 ) return SQLITE_NOMEM; 177f5e7bb51Sdrh } 1781feb7dd3Sdrh p = p->u.apSub[bin]; 179f5e7bb51Sdrh } 1801feb7dd3Sdrh if( p->iSize<=BITVEC_NBIT ){ 1811feb7dd3Sdrh p->u.aBitmap[i/BITVEC_SZELEM] |= 1 << (i&(BITVEC_SZELEM-1)); 1821feb7dd3Sdrh return SQLITE_OK; 1831feb7dd3Sdrh } 1841feb7dd3Sdrh h = BITVEC_HASH(i++); 1851feb7dd3Sdrh /* if there wasn't a hash collision, and this doesn't */ 1861feb7dd3Sdrh /* completely fill the hash, then just add it without */ 1871feb7dd3Sdrh /* worring about sub-dividing and re-hashing. */ 1881feb7dd3Sdrh if( !p->u.aHash[h] ){ 1891feb7dd3Sdrh if (p->nSet<(BITVEC_NINT-1)) { 1901feb7dd3Sdrh goto bitvec_set_end; 1911feb7dd3Sdrh } else { 1921feb7dd3Sdrh goto bitvec_set_rehash; 1931feb7dd3Sdrh } 1941feb7dd3Sdrh } 1951feb7dd3Sdrh /* there was a collision, check to see if it's already */ 1961feb7dd3Sdrh /* in hash, if not, try to find a spot for it */ 1971feb7dd3Sdrh do { 198f5e7bb51Sdrh if( p->u.aHash[h]==i ) return SQLITE_OK; 199f5e7bb51Sdrh h++; 2001feb7dd3Sdrh if( h>=BITVEC_NINT ) h = 0; 2011feb7dd3Sdrh } while( p->u.aHash[h] ); 2021feb7dd3Sdrh /* we didn't find it in the hash. h points to the first */ 2031feb7dd3Sdrh /* available free spot. check to see if this is going to */ 2041feb7dd3Sdrh /* make our hash too "full". */ 2051feb7dd3Sdrh bitvec_set_rehash: 206f5e7bb51Sdrh if( p->nSet>=BITVEC_MXHASH ){ 20786a7a69cSdrh unsigned int j; 20886a7a69cSdrh int rc; 209e98c9049Sdrh u32 *aiValues = sqlite3StackAllocRaw(0, sizeof(p->u.aHash)); 210e98c9049Sdrh if( aiValues==0 ){ 211e98c9049Sdrh return SQLITE_NOMEM; 212e98c9049Sdrh }else{ 213e98c9049Sdrh memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash)); 214e98c9049Sdrh memset(p->u.apSub, 0, sizeof(p->u.apSub)); 215f5e7bb51Sdrh p->iDivisor = (p->iSize + BITVEC_NPTR - 1)/BITVEC_NPTR; 2163088d59eSdrh rc = sqlite3BitvecSet(p, i); 2173088d59eSdrh for(j=0; j<BITVEC_NINT; j++){ 218f5e7bb51Sdrh if( aiValues[j] ) rc |= sqlite3BitvecSet(p, aiValues[j]); 219f5e7bb51Sdrh } 220e98c9049Sdrh sqlite3StackFree(0, aiValues); 221f5e7bb51Sdrh return rc; 222f5e7bb51Sdrh } 223e98c9049Sdrh } 2241feb7dd3Sdrh bitvec_set_end: 2251feb7dd3Sdrh p->nSet++; 226f5e7bb51Sdrh p->u.aHash[h] = i; 227f5e7bb51Sdrh return SQLITE_OK; 228f5e7bb51Sdrh } 229f5e7bb51Sdrh 230f5e7bb51Sdrh /* 2311feb7dd3Sdrh ** Clear the i-th bit. 232e98c9049Sdrh ** 233e98c9049Sdrh ** pBuf must be a pointer to at least BITVEC_SZ bytes of temporary storage 234e98c9049Sdrh ** that BitvecClear can use to rebuilt its hash table. 235f5e7bb51Sdrh */ 236e98c9049Sdrh void sqlite3BitvecClear(Bitvec *p, u32 i, void *pBuf){ 2376aac11dcSdrh if( p==0 ) return; 2383088d59eSdrh assert( i>0 ); 239f5e7bb51Sdrh i--; 2401feb7dd3Sdrh while( p->iDivisor ){ 2411feb7dd3Sdrh u32 bin = i/p->iDivisor; 2421feb7dd3Sdrh i = i%p->iDivisor; 2431feb7dd3Sdrh p = p->u.apSub[bin]; 2441feb7dd3Sdrh if (!p) { 2451feb7dd3Sdrh return; 246f5e7bb51Sdrh } 2471feb7dd3Sdrh } 2481feb7dd3Sdrh if( p->iSize<=BITVEC_NBIT ){ 2491feb7dd3Sdrh p->u.aBitmap[i/BITVEC_SZELEM] &= ~(1 << (i&(BITVEC_SZELEM-1))); 250f5e7bb51Sdrh }else{ 25186a7a69cSdrh unsigned int j; 252e98c9049Sdrh u32 *aiValues = pBuf; 253e98c9049Sdrh memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash)); 254e98c9049Sdrh memset(p->u.aHash, 0, sizeof(p->u.aHash)); 255f5e7bb51Sdrh p->nSet = 0; 256f5e7bb51Sdrh for(j=0; j<BITVEC_NINT; j++){ 2571feb7dd3Sdrh if( aiValues[j] && aiValues[j]!=(i+1) ){ 2581feb7dd3Sdrh u32 h = BITVEC_HASH(aiValues[j]-1); 2591feb7dd3Sdrh p->nSet++; 2601feb7dd3Sdrh while( p->u.aHash[h] ){ 2611feb7dd3Sdrh h++; 2621feb7dd3Sdrh if( h>=BITVEC_NINT ) h = 0; 2631feb7dd3Sdrh } 2641feb7dd3Sdrh p->u.aHash[h] = aiValues[j]; 2653088d59eSdrh } 266f5e7bb51Sdrh } 267f5e7bb51Sdrh } 268f5e7bb51Sdrh } 269f5e7bb51Sdrh 270f5e7bb51Sdrh /* 271f5e7bb51Sdrh ** Destroy a bitmap object. Reclaim all memory used. 272f5e7bb51Sdrh */ 273f5e7bb51Sdrh void sqlite3BitvecDestroy(Bitvec *p){ 274f5e7bb51Sdrh if( p==0 ) return; 275f5e7bb51Sdrh if( p->iDivisor ){ 27686a7a69cSdrh unsigned int i; 277f5e7bb51Sdrh for(i=0; i<BITVEC_NPTR; i++){ 278f5e7bb51Sdrh sqlite3BitvecDestroy(p->u.apSub[i]); 279f5e7bb51Sdrh } 280f5e7bb51Sdrh } 281f5e7bb51Sdrh sqlite3_free(p); 282f5e7bb51Sdrh } 2833088d59eSdrh 284bea2a948Sdanielk1977 /* 285bea2a948Sdanielk1977 ** Return the value of the iSize parameter specified when Bitvec *p 286bea2a948Sdanielk1977 ** was created. 287bea2a948Sdanielk1977 */ 288bea2a948Sdanielk1977 u32 sqlite3BitvecSize(Bitvec *p){ 289bea2a948Sdanielk1977 return p->iSize; 290bea2a948Sdanielk1977 } 291bea2a948Sdanielk1977 2923088d59eSdrh #ifndef SQLITE_OMIT_BUILTIN_TEST 2933088d59eSdrh /* 2943088d59eSdrh ** Let V[] be an array of unsigned characters sufficient to hold 2953088d59eSdrh ** up to N bits. Let I be an integer between 0 and N. 0<=I<N. 2963088d59eSdrh ** Then the following macros can be used to set, clear, or test 2973088d59eSdrh ** individual bits within V. 2983088d59eSdrh */ 2993088d59eSdrh #define SETBIT(V,I) V[I>>3] |= (1<<(I&7)) 3003088d59eSdrh #define CLEARBIT(V,I) V[I>>3] &= ~(1<<(I&7)) 3013088d59eSdrh #define TESTBIT(V,I) (V[I>>3]&(1<<(I&7)))!=0 3023088d59eSdrh 3033088d59eSdrh /* 3043088d59eSdrh ** This routine runs an extensive test of the Bitvec code. 3053088d59eSdrh ** 3063088d59eSdrh ** The input is an array of integers that acts as a program 3073088d59eSdrh ** to test the Bitvec. The integers are opcodes followed 3083088d59eSdrh ** by 0, 1, or 3 operands, depending on the opcode. Another 3093088d59eSdrh ** opcode follows immediately after the last operand. 3103088d59eSdrh ** 3113088d59eSdrh ** There are 6 opcodes numbered from 0 through 5. 0 is the 3123088d59eSdrh ** "halt" opcode and causes the test to end. 3133088d59eSdrh ** 3143088d59eSdrh ** 0 Halt and return the number of errors 3153088d59eSdrh ** 1 N S X Set N bits beginning with S and incrementing by X 3163088d59eSdrh ** 2 N S X Clear N bits beginning with S and incrementing by X 3173088d59eSdrh ** 3 N Set N randomly chosen bits 3183088d59eSdrh ** 4 N Clear N randomly chosen bits 3193088d59eSdrh ** 5 N S X Set N bits from S increment X in array only, not in bitvec 3203088d59eSdrh ** 3213088d59eSdrh ** The opcodes 1 through 4 perform set and clear operations are performed 3223088d59eSdrh ** on both a Bitvec object and on a linear array of bits obtained from malloc. 3233088d59eSdrh ** Opcode 5 works on the linear array only, not on the Bitvec. 3243088d59eSdrh ** Opcode 5 is used to deliberately induce a fault in order to 3253088d59eSdrh ** confirm that error detection works. 3263088d59eSdrh ** 3273088d59eSdrh ** At the conclusion of the test the linear array is compared 3283088d59eSdrh ** against the Bitvec object. If there are any differences, 3293088d59eSdrh ** an error is returned. If they are the same, zero is returned. 3303088d59eSdrh ** 3313088d59eSdrh ** If a memory allocation error occurs, return -1. 3323088d59eSdrh */ 3333088d59eSdrh int sqlite3BitvecBuiltinTest(int sz, int *aOp){ 3343088d59eSdrh Bitvec *pBitvec = 0; 3353088d59eSdrh unsigned char *pV = 0; 3363088d59eSdrh int rc = -1; 3373088d59eSdrh int i, nx, pc, op; 338e98c9049Sdrh void *pTmpSpace; 3393088d59eSdrh 3403088d59eSdrh /* Allocate the Bitvec to be tested and a linear array of 3413088d59eSdrh ** bits to act as the reference */ 3423088d59eSdrh pBitvec = sqlite3BitvecCreate( sz ); 3436809c96dSdan pV = sqlite3MallocZero( (sz+7)/8 + 1 ); 344*f3cdcdccSdrh pTmpSpace = sqlite3_malloc64(BITVEC_SZ); 345e98c9049Sdrh if( pBitvec==0 || pV==0 || pTmpSpace==0 ) goto bitvec_end; 3463088d59eSdrh 3476aac11dcSdrh /* NULL pBitvec tests */ 3486aac11dcSdrh sqlite3BitvecSet(0, 1); 3496aac11dcSdrh sqlite3BitvecClear(0, 1, pTmpSpace); 3506aac11dcSdrh 3513088d59eSdrh /* Run the program */ 3523088d59eSdrh pc = 0; 3533088d59eSdrh while( (op = aOp[pc])!=0 ){ 3543088d59eSdrh switch( op ){ 3553088d59eSdrh case 1: 3563088d59eSdrh case 2: 3573088d59eSdrh case 5: { 3583088d59eSdrh nx = 4; 3593088d59eSdrh i = aOp[pc+2] - 1; 3603088d59eSdrh aOp[pc+2] += aOp[pc+3]; 3613088d59eSdrh break; 3623088d59eSdrh } 3633088d59eSdrh case 3: 3643088d59eSdrh case 4: 3653088d59eSdrh default: { 3663088d59eSdrh nx = 2; 3673088d59eSdrh sqlite3_randomness(sizeof(i), &i); 3683088d59eSdrh break; 3693088d59eSdrh } 3703088d59eSdrh } 3713088d59eSdrh if( (--aOp[pc+1]) > 0 ) nx = 0; 3723088d59eSdrh pc += nx; 3733088d59eSdrh i = (i & 0x7fffffff)%sz; 3743088d59eSdrh if( (op & 1)!=0 ){ 3753088d59eSdrh SETBIT(pV, (i+1)); 3763088d59eSdrh if( op!=5 ){ 3773088d59eSdrh if( sqlite3BitvecSet(pBitvec, i+1) ) goto bitvec_end; 3783088d59eSdrh } 3793088d59eSdrh }else{ 3803088d59eSdrh CLEARBIT(pV, (i+1)); 381e98c9049Sdrh sqlite3BitvecClear(pBitvec, i+1, pTmpSpace); 3823088d59eSdrh } 3833088d59eSdrh } 3843088d59eSdrh 3853088d59eSdrh /* Test to make sure the linear array exactly matches the 3863088d59eSdrh ** Bitvec object. Start with the assumption that they do 3873088d59eSdrh ** match (rc==0). Change rc to non-zero if a discrepancy 3883088d59eSdrh ** is found. 3893088d59eSdrh */ 3903088d59eSdrh rc = sqlite3BitvecTest(0,0) + sqlite3BitvecTest(pBitvec, sz+1) 39164f798ddSdrh + sqlite3BitvecTest(pBitvec, 0) 39264f798ddSdrh + (sqlite3BitvecSize(pBitvec) - sz); 3933088d59eSdrh for(i=1; i<=sz; i++){ 3943088d59eSdrh if( (TESTBIT(pV,i))!=sqlite3BitvecTest(pBitvec,i) ){ 3953088d59eSdrh rc = i; 3963088d59eSdrh break; 3973088d59eSdrh } 3983088d59eSdrh } 3993088d59eSdrh 4003088d59eSdrh /* Free allocated structure */ 4013088d59eSdrh bitvec_end: 402e98c9049Sdrh sqlite3_free(pTmpSpace); 4033088d59eSdrh sqlite3_free(pV); 4043088d59eSdrh sqlite3BitvecDestroy(pBitvec); 4053088d59eSdrh return rc; 4063088d59eSdrh } 4073088d59eSdrh #endif /* SQLITE_OMIT_BUILTIN_TEST */ 408