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. */
4462aaa6caSdrh #define BITVEC_USIZE \
4562aaa6caSdrh (((BITVEC_SZ-(3*sizeof(u32)))/sizeof(Bitvec*))*sizeof(Bitvec*))
461feb7dd3Sdrh
471feb7dd3Sdrh /* Type of the array "element" for the bitmap representation.
481feb7dd3Sdrh ** Should be a power of 2, and ideally, evenly divide into BITVEC_USIZE.
491feb7dd3Sdrh ** Setting this to the "natural word" size of your CPU may improve
501feb7dd3Sdrh ** performance. */
511feb7dd3Sdrh #define BITVEC_TELEM u8
521feb7dd3Sdrh /* Size, in bits, of the bitmap element. */
531feb7dd3Sdrh #define BITVEC_SZELEM 8
541feb7dd3Sdrh /* Number of elements in a bitmap array. */
551feb7dd3Sdrh #define BITVEC_NELEM (BITVEC_USIZE/sizeof(BITVEC_TELEM))
561feb7dd3Sdrh /* Number of bits in the bitmap array. */
571feb7dd3Sdrh #define BITVEC_NBIT (BITVEC_NELEM*BITVEC_SZELEM)
581feb7dd3Sdrh
591feb7dd3Sdrh /* Number of u32 values in hash table. */
601feb7dd3Sdrh #define BITVEC_NINT (BITVEC_USIZE/sizeof(u32))
611feb7dd3Sdrh /* Maximum number of entries in hash table before
621feb7dd3Sdrh ** sub-dividing and re-hashing. */
63f5e7bb51Sdrh #define BITVEC_MXHASH (BITVEC_NINT/2)
641feb7dd3Sdrh /* Hashing function for the aHash representation.
651feb7dd3Sdrh ** Empirical testing showed that the *37 multiplier
661feb7dd3Sdrh ** (an arbitrary prime)in the hash function provided
671feb7dd3Sdrh ** no fewer collisions than the no-op *1. */
681feb7dd3Sdrh #define BITVEC_HASH(X) (((X)*1)%BITVEC_NINT)
691feb7dd3Sdrh
70dda5b68cSmlcreech #define BITVEC_NPTR (BITVEC_USIZE/sizeof(Bitvec *))
71f5e7bb51Sdrh
72f5e7bb51Sdrh
73f5e7bb51Sdrh /*
74f5e7bb51Sdrh ** A bitmap is an instance of the following structure.
75f5e7bb51Sdrh **
7648864df9Smistachkin ** This bitmap records the existence of zero or more bits
77f5e7bb51Sdrh ** with values between 1 and iSize, inclusive.
78f5e7bb51Sdrh **
79f5e7bb51Sdrh ** There are three possible representations of the bitmap.
80f5e7bb51Sdrh ** If iSize<=BITVEC_NBIT, then Bitvec.u.aBitmap[] is a straight
81f5e7bb51Sdrh ** bitmap. The least significant bit is bit 1.
82f5e7bb51Sdrh **
83f5e7bb51Sdrh ** If iSize>BITVEC_NBIT and iDivisor==0 then Bitvec.u.aHash[] is
84f5e7bb51Sdrh ** a hash table that will hold up to BITVEC_MXHASH distinct values.
85f5e7bb51Sdrh **
86f5e7bb51Sdrh ** Otherwise, the value i is redirected into one of BITVEC_NPTR
87f5e7bb51Sdrh ** sub-bitmaps pointed to by Bitvec.u.apSub[]. Each subbitmap
88f5e7bb51Sdrh ** handles up to iDivisor separate values of i. apSub[0] holds
89f5e7bb51Sdrh ** values between 1 and iDivisor. apSub[1] holds values between
90f5e7bb51Sdrh ** iDivisor+1 and 2*iDivisor. apSub[N] holds values between
91f5e7bb51Sdrh ** N*iDivisor+1 and (N+1)*iDivisor. Each subbitmap is normalized
92f5e7bb51Sdrh ** to hold deal with values between 1 and iDivisor.
93f5e7bb51Sdrh */
94f5e7bb51Sdrh struct Bitvec {
951feb7dd3Sdrh u32 iSize; /* Maximum bit index. Max iSize is 4,294,967,296. */
9664f798ddSdrh u32 nSet; /* Number of bits that are set - only valid for aHash
9764f798ddSdrh ** element. Max is BITVEC_NINT. For BITVEC_SZ of 512,
9864f798ddSdrh ** this would be 125. */
991feb7dd3Sdrh u32 iDivisor; /* Number of bits handled by each apSub[] entry. */
1001feb7dd3Sdrh /* Should >=0 for apSub element. */
1011feb7dd3Sdrh /* Max iDivisor is max(u32) / BITVEC_NPTR + 1. */
1021feb7dd3Sdrh /* For a BITVEC_SZ of 512, this would be 34,359,739. */
103f5e7bb51Sdrh union {
1041feb7dd3Sdrh BITVEC_TELEM aBitmap[BITVEC_NELEM]; /* Bitmap representation */
105f5e7bb51Sdrh u32 aHash[BITVEC_NINT]; /* Hash table representation */
106f5e7bb51Sdrh Bitvec *apSub[BITVEC_NPTR]; /* Recursive representation */
107f5e7bb51Sdrh } u;
108f5e7bb51Sdrh };
109f5e7bb51Sdrh
110f5e7bb51Sdrh /*
111f5e7bb51Sdrh ** Create a new bitmap object able to handle bits between 0 and iSize,
112f5e7bb51Sdrh ** inclusive. Return a pointer to the new object. Return NULL if
113f5e7bb51Sdrh ** malloc fails.
114f5e7bb51Sdrh */
sqlite3BitvecCreate(u32 iSize)115f5e7bb51Sdrh Bitvec *sqlite3BitvecCreate(u32 iSize){
116f5e7bb51Sdrh Bitvec *p;
117f5e7bb51Sdrh assert( sizeof(*p)==BITVEC_SZ );
118f5e7bb51Sdrh p = sqlite3MallocZero( sizeof(*p) );
119f5e7bb51Sdrh if( p ){
120f5e7bb51Sdrh p->iSize = iSize;
121f5e7bb51Sdrh }
122f5e7bb51Sdrh return p;
123f5e7bb51Sdrh }
124f5e7bb51Sdrh
125f5e7bb51Sdrh /*
126f5e7bb51Sdrh ** Check to see if the i-th bit is set. Return true or false.
127f5e7bb51Sdrh ** If p is NULL (if the bitmap has not been created) or if
128f5e7bb51Sdrh ** i is out of range, then return false.
129f5e7bb51Sdrh */
sqlite3BitvecTestNotNull(Bitvec * p,u32 i)13082ef8775Sdrh int sqlite3BitvecTestNotNull(Bitvec *p, u32 i){
13182ef8775Sdrh assert( p!=0 );
132f5e7bb51Sdrh i--;
133234a93fcSdrh if( i>=p->iSize ) return 0;
1341feb7dd3Sdrh while( p->iDivisor ){
1351feb7dd3Sdrh u32 bin = i/p->iDivisor;
1361feb7dd3Sdrh i = i%p->iDivisor;
1371feb7dd3Sdrh p = p->u.apSub[bin];
1381feb7dd3Sdrh if (!p) {
1391feb7dd3Sdrh return 0;
140f5e7bb51Sdrh }
1411feb7dd3Sdrh }
1421feb7dd3Sdrh if( p->iSize<=BITVEC_NBIT ){
1431feb7dd3Sdrh return (p->u.aBitmap[i/BITVEC_SZELEM] & (1<<(i&(BITVEC_SZELEM-1))))!=0;
144f5e7bb51Sdrh } else{
1451feb7dd3Sdrh u32 h = BITVEC_HASH(i++);
146f5e7bb51Sdrh while( p->u.aHash[h] ){
147f5e7bb51Sdrh if( p->u.aHash[h]==i ) return 1;
1487ee27b07Sdrh h = (h+1) % BITVEC_NINT;
149f5e7bb51Sdrh }
150f5e7bb51Sdrh return 0;
151f5e7bb51Sdrh }
152f5e7bb51Sdrh }
sqlite3BitvecTest(Bitvec * p,u32 i)15382ef8775Sdrh int sqlite3BitvecTest(Bitvec *p, u32 i){
15482ef8775Sdrh return p!=0 && sqlite3BitvecTestNotNull(p,i);
15582ef8775Sdrh }
156f5e7bb51Sdrh
157f5e7bb51Sdrh /*
158f5e7bb51Sdrh ** Set the i-th bit. Return 0 on success and an error code if
159f5e7bb51Sdrh ** anything goes wrong.
160dfe88eceSdrh **
161dfe88eceSdrh ** This routine might cause sub-bitmaps to be allocated. Failing
162dfe88eceSdrh ** to get the memory needed to hold the sub-bitmap is the only
163dfe88eceSdrh ** that can go wrong with an insert, assuming p and i are valid.
164dfe88eceSdrh **
165dfe88eceSdrh ** The calling function must ensure that p is a valid Bitvec object
166dfe88eceSdrh ** and that the value for "i" is within range of the Bitvec object.
167dfe88eceSdrh ** Otherwise the behavior is undefined.
168f5e7bb51Sdrh */
sqlite3BitvecSet(Bitvec * p,u32 i)169f5e7bb51Sdrh int sqlite3BitvecSet(Bitvec *p, u32 i){
170f5e7bb51Sdrh u32 h;
1716aac11dcSdrh if( p==0 ) return SQLITE_OK;
1723088d59eSdrh assert( i>0 );
173c5d0bd90Sdrh assert( i<=p->iSize );
174f5e7bb51Sdrh i--;
1751feb7dd3Sdrh while((p->iSize > BITVEC_NBIT) && p->iDivisor) {
1761feb7dd3Sdrh u32 bin = i/p->iDivisor;
1771feb7dd3Sdrh i = i%p->iDivisor;
178f5e7bb51Sdrh if( p->u.apSub[bin]==0 ){
179f5e7bb51Sdrh p->u.apSub[bin] = sqlite3BitvecCreate( p->iDivisor );
180fad3039cSmistachkin if( p->u.apSub[bin]==0 ) return SQLITE_NOMEM_BKPT;
181f5e7bb51Sdrh }
1821feb7dd3Sdrh p = p->u.apSub[bin];
183f5e7bb51Sdrh }
1841feb7dd3Sdrh if( p->iSize<=BITVEC_NBIT ){
1851feb7dd3Sdrh p->u.aBitmap[i/BITVEC_SZELEM] |= 1 << (i&(BITVEC_SZELEM-1));
1861feb7dd3Sdrh return SQLITE_OK;
1871feb7dd3Sdrh }
1881feb7dd3Sdrh h = BITVEC_HASH(i++);
1891feb7dd3Sdrh /* if there wasn't a hash collision, and this doesn't */
1901feb7dd3Sdrh /* completely fill the hash, then just add it without */
1911feb7dd3Sdrh /* worring about sub-dividing and re-hashing. */
1921feb7dd3Sdrh if( !p->u.aHash[h] ){
1931feb7dd3Sdrh if (p->nSet<(BITVEC_NINT-1)) {
1941feb7dd3Sdrh goto bitvec_set_end;
1951feb7dd3Sdrh } else {
1961feb7dd3Sdrh goto bitvec_set_rehash;
1971feb7dd3Sdrh }
1981feb7dd3Sdrh }
1991feb7dd3Sdrh /* there was a collision, check to see if it's already */
2001feb7dd3Sdrh /* in hash, if not, try to find a spot for it */
2011feb7dd3Sdrh do {
202f5e7bb51Sdrh if( p->u.aHash[h]==i ) return SQLITE_OK;
203f5e7bb51Sdrh h++;
2041feb7dd3Sdrh if( h>=BITVEC_NINT ) h = 0;
2051feb7dd3Sdrh } while( p->u.aHash[h] );
2061feb7dd3Sdrh /* we didn't find it in the hash. h points to the first */
2071feb7dd3Sdrh /* available free spot. check to see if this is going to */
2081feb7dd3Sdrh /* make our hash too "full". */
2091feb7dd3Sdrh bitvec_set_rehash:
210f5e7bb51Sdrh if( p->nSet>=BITVEC_MXHASH ){
21186a7a69cSdrh unsigned int j;
21286a7a69cSdrh int rc;
213e98c9049Sdrh u32 *aiValues = sqlite3StackAllocRaw(0, sizeof(p->u.aHash));
214e98c9049Sdrh if( aiValues==0 ){
215fad3039cSmistachkin return SQLITE_NOMEM_BKPT;
216e98c9049Sdrh }else{
217e98c9049Sdrh memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash));
218e98c9049Sdrh memset(p->u.apSub, 0, sizeof(p->u.apSub));
219f5e7bb51Sdrh p->iDivisor = (p->iSize + BITVEC_NPTR - 1)/BITVEC_NPTR;
2203088d59eSdrh rc = sqlite3BitvecSet(p, i);
2213088d59eSdrh for(j=0; j<BITVEC_NINT; j++){
222f5e7bb51Sdrh if( aiValues[j] ) rc |= sqlite3BitvecSet(p, aiValues[j]);
223f5e7bb51Sdrh }
224e98c9049Sdrh sqlite3StackFree(0, aiValues);
225f5e7bb51Sdrh return rc;
226f5e7bb51Sdrh }
227e98c9049Sdrh }
2281feb7dd3Sdrh bitvec_set_end:
2291feb7dd3Sdrh p->nSet++;
230f5e7bb51Sdrh p->u.aHash[h] = i;
231f5e7bb51Sdrh return SQLITE_OK;
232f5e7bb51Sdrh }
233f5e7bb51Sdrh
234f5e7bb51Sdrh /*
2351feb7dd3Sdrh ** Clear the i-th bit.
236e98c9049Sdrh **
237e98c9049Sdrh ** pBuf must be a pointer to at least BITVEC_SZ bytes of temporary storage
238e98c9049Sdrh ** that BitvecClear can use to rebuilt its hash table.
239f5e7bb51Sdrh */
sqlite3BitvecClear(Bitvec * p,u32 i,void * pBuf)240e98c9049Sdrh void sqlite3BitvecClear(Bitvec *p, u32 i, void *pBuf){
2416aac11dcSdrh if( p==0 ) return;
2423088d59eSdrh assert( i>0 );
243f5e7bb51Sdrh i--;
2441feb7dd3Sdrh while( p->iDivisor ){
2451feb7dd3Sdrh u32 bin = i/p->iDivisor;
2461feb7dd3Sdrh i = i%p->iDivisor;
2471feb7dd3Sdrh p = p->u.apSub[bin];
2481feb7dd3Sdrh if (!p) {
2491feb7dd3Sdrh return;
250f5e7bb51Sdrh }
2511feb7dd3Sdrh }
2521feb7dd3Sdrh if( p->iSize<=BITVEC_NBIT ){
2531feb7dd3Sdrh p->u.aBitmap[i/BITVEC_SZELEM] &= ~(1 << (i&(BITVEC_SZELEM-1)));
254f5e7bb51Sdrh }else{
25586a7a69cSdrh unsigned int j;
256e98c9049Sdrh u32 *aiValues = pBuf;
257e98c9049Sdrh memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash));
258e98c9049Sdrh memset(p->u.aHash, 0, sizeof(p->u.aHash));
259f5e7bb51Sdrh p->nSet = 0;
260f5e7bb51Sdrh for(j=0; j<BITVEC_NINT; j++){
2611feb7dd3Sdrh if( aiValues[j] && aiValues[j]!=(i+1) ){
2621feb7dd3Sdrh u32 h = BITVEC_HASH(aiValues[j]-1);
2631feb7dd3Sdrh p->nSet++;
2641feb7dd3Sdrh while( p->u.aHash[h] ){
2651feb7dd3Sdrh h++;
2661feb7dd3Sdrh if( h>=BITVEC_NINT ) h = 0;
2671feb7dd3Sdrh }
2681feb7dd3Sdrh p->u.aHash[h] = aiValues[j];
2693088d59eSdrh }
270f5e7bb51Sdrh }
271f5e7bb51Sdrh }
272f5e7bb51Sdrh }
273f5e7bb51Sdrh
274f5e7bb51Sdrh /*
275f5e7bb51Sdrh ** Destroy a bitmap object. Reclaim all memory used.
276f5e7bb51Sdrh */
sqlite3BitvecDestroy(Bitvec * p)277f5e7bb51Sdrh void sqlite3BitvecDestroy(Bitvec *p){
278f5e7bb51Sdrh if( p==0 ) return;
279f5e7bb51Sdrh if( p->iDivisor ){
28086a7a69cSdrh unsigned int i;
281f5e7bb51Sdrh for(i=0; i<BITVEC_NPTR; i++){
282f5e7bb51Sdrh sqlite3BitvecDestroy(p->u.apSub[i]);
283f5e7bb51Sdrh }
284f5e7bb51Sdrh }
285f5e7bb51Sdrh sqlite3_free(p);
286f5e7bb51Sdrh }
2873088d59eSdrh
288bea2a948Sdanielk1977 /*
289bea2a948Sdanielk1977 ** Return the value of the iSize parameter specified when Bitvec *p
290bea2a948Sdanielk1977 ** was created.
291bea2a948Sdanielk1977 */
sqlite3BitvecSize(Bitvec * p)292bea2a948Sdanielk1977 u32 sqlite3BitvecSize(Bitvec *p){
293bea2a948Sdanielk1977 return p->iSize;
294bea2a948Sdanielk1977 }
295bea2a948Sdanielk1977
296d12602a9Sdrh #ifndef SQLITE_UNTESTABLE
2973088d59eSdrh /*
2983088d59eSdrh ** Let V[] be an array of unsigned characters sufficient to hold
2993088d59eSdrh ** up to N bits. Let I be an integer between 0 and N. 0<=I<N.
3003088d59eSdrh ** Then the following macros can be used to set, clear, or test
3013088d59eSdrh ** individual bits within V.
3023088d59eSdrh */
3033088d59eSdrh #define SETBIT(V,I) V[I>>3] |= (1<<(I&7))
3043088d59eSdrh #define CLEARBIT(V,I) V[I>>3] &= ~(1<<(I&7))
3053088d59eSdrh #define TESTBIT(V,I) (V[I>>3]&(1<<(I&7)))!=0
3063088d59eSdrh
3073088d59eSdrh /*
3083088d59eSdrh ** This routine runs an extensive test of the Bitvec code.
3093088d59eSdrh **
3103088d59eSdrh ** The input is an array of integers that acts as a program
3113088d59eSdrh ** to test the Bitvec. The integers are opcodes followed
3123088d59eSdrh ** by 0, 1, or 3 operands, depending on the opcode. Another
3133088d59eSdrh ** opcode follows immediately after the last operand.
3143088d59eSdrh **
3153088d59eSdrh ** There are 6 opcodes numbered from 0 through 5. 0 is the
3163088d59eSdrh ** "halt" opcode and causes the test to end.
3173088d59eSdrh **
3183088d59eSdrh ** 0 Halt and return the number of errors
3193088d59eSdrh ** 1 N S X Set N bits beginning with S and incrementing by X
3203088d59eSdrh ** 2 N S X Clear N bits beginning with S and incrementing by X
3213088d59eSdrh ** 3 N Set N randomly chosen bits
3223088d59eSdrh ** 4 N Clear N randomly chosen bits
3233088d59eSdrh ** 5 N S X Set N bits from S increment X in array only, not in bitvec
3243088d59eSdrh **
3253088d59eSdrh ** The opcodes 1 through 4 perform set and clear operations are performed
3263088d59eSdrh ** on both a Bitvec object and on a linear array of bits obtained from malloc.
3273088d59eSdrh ** Opcode 5 works on the linear array only, not on the Bitvec.
3283088d59eSdrh ** Opcode 5 is used to deliberately induce a fault in order to
3293088d59eSdrh ** confirm that error detection works.
3303088d59eSdrh **
3313088d59eSdrh ** At the conclusion of the test the linear array is compared
3323088d59eSdrh ** against the Bitvec object. If there are any differences,
3333088d59eSdrh ** an error is returned. If they are the same, zero is returned.
3343088d59eSdrh **
3353088d59eSdrh ** If a memory allocation error occurs, return -1.
3363088d59eSdrh */
sqlite3BitvecBuiltinTest(int sz,int * aOp)3373088d59eSdrh int sqlite3BitvecBuiltinTest(int sz, int *aOp){
3383088d59eSdrh Bitvec *pBitvec = 0;
3393088d59eSdrh unsigned char *pV = 0;
3403088d59eSdrh int rc = -1;
3413088d59eSdrh int i, nx, pc, op;
342e98c9049Sdrh void *pTmpSpace;
3433088d59eSdrh
3443088d59eSdrh /* Allocate the Bitvec to be tested and a linear array of
3453088d59eSdrh ** bits to act as the reference */
3463088d59eSdrh pBitvec = sqlite3BitvecCreate( sz );
3476809c96dSdan pV = sqlite3MallocZero( (sz+7)/8 + 1 );
348f3cdcdccSdrh pTmpSpace = sqlite3_malloc64(BITVEC_SZ);
349e98c9049Sdrh if( pBitvec==0 || pV==0 || pTmpSpace==0 ) goto bitvec_end;
3503088d59eSdrh
3516aac11dcSdrh /* NULL pBitvec tests */
3526aac11dcSdrh sqlite3BitvecSet(0, 1);
3536aac11dcSdrh sqlite3BitvecClear(0, 1, pTmpSpace);
3546aac11dcSdrh
3553088d59eSdrh /* Run the program */
356*7d4c94bcSdrh pc = i = 0;
3573088d59eSdrh while( (op = aOp[pc])!=0 ){
3583088d59eSdrh switch( op ){
3593088d59eSdrh case 1:
3603088d59eSdrh case 2:
3613088d59eSdrh case 5: {
3623088d59eSdrh nx = 4;
3633088d59eSdrh i = aOp[pc+2] - 1;
3643088d59eSdrh aOp[pc+2] += aOp[pc+3];
3653088d59eSdrh break;
3663088d59eSdrh }
3673088d59eSdrh case 3:
3683088d59eSdrh case 4:
3693088d59eSdrh default: {
3703088d59eSdrh nx = 2;
3713088d59eSdrh sqlite3_randomness(sizeof(i), &i);
3723088d59eSdrh break;
3733088d59eSdrh }
3743088d59eSdrh }
3753088d59eSdrh if( (--aOp[pc+1]) > 0 ) nx = 0;
3763088d59eSdrh pc += nx;
3773088d59eSdrh i = (i & 0x7fffffff)%sz;
3783088d59eSdrh if( (op & 1)!=0 ){
3793088d59eSdrh SETBIT(pV, (i+1));
3803088d59eSdrh if( op!=5 ){
3813088d59eSdrh if( sqlite3BitvecSet(pBitvec, i+1) ) goto bitvec_end;
3823088d59eSdrh }
3833088d59eSdrh }else{
3843088d59eSdrh CLEARBIT(pV, (i+1));
385e98c9049Sdrh sqlite3BitvecClear(pBitvec, i+1, pTmpSpace);
3863088d59eSdrh }
3873088d59eSdrh }
3883088d59eSdrh
3893088d59eSdrh /* Test to make sure the linear array exactly matches the
3903088d59eSdrh ** Bitvec object. Start with the assumption that they do
3913088d59eSdrh ** match (rc==0). Change rc to non-zero if a discrepancy
3923088d59eSdrh ** is found.
3933088d59eSdrh */
3943088d59eSdrh rc = sqlite3BitvecTest(0,0) + sqlite3BitvecTest(pBitvec, sz+1)
39564f798ddSdrh + sqlite3BitvecTest(pBitvec, 0)
39664f798ddSdrh + (sqlite3BitvecSize(pBitvec) - sz);
3973088d59eSdrh for(i=1; i<=sz; i++){
3983088d59eSdrh if( (TESTBIT(pV,i))!=sqlite3BitvecTest(pBitvec,i) ){
3993088d59eSdrh rc = i;
4003088d59eSdrh break;
4013088d59eSdrh }
4023088d59eSdrh }
4033088d59eSdrh
4043088d59eSdrh /* Free allocated structure */
4053088d59eSdrh bitvec_end:
406e98c9049Sdrh sqlite3_free(pTmpSpace);
4073088d59eSdrh sqlite3_free(pV);
4083088d59eSdrh sqlite3BitvecDestroy(pBitvec);
4093088d59eSdrh return rc;
4103088d59eSdrh }
411d12602a9Sdrh #endif /* SQLITE_UNTESTABLE */
412