3 #include "bp-darray.h"
\r
5 #define PBS (sizeof(pb)*8)
\r
11 #define logLL 16 // size of word
\r
12 #define LL (1<<logLL)
\r
15 #define LLL (1<<logLLL)
\r
17 //#define logL (logLL-3)
\r
18 #define logL (logLL-1-5)
\r
22 ({ __typeof__ (a) _a = (a); \
\r
23 __typeof__ (b) _b = (b); \
\r
24 _a > _b ? _a : _b; })
\r
28 ({ __typeof__ (a) _a = (a); \
\r
29 __typeof__ (b) _b = (b); \
\r
30 _a <= _b ? _a : _b; })
\r
35 static dword getbits(pb *B, int i, int d)
\r
40 for (j=0; j<d; j++) {
\r
42 x += bp_getbit(B,i+j);
\r
47 static int getpattern(pb *B, int i, int k, pb pat)
\r
52 for (j=0; j<k; j++) {
\r
53 x &= bp_getbit(B,i+j) ^ (~(pat>>(k-1-j)));
\r
55 //printf("getpattern(%d) = %d\n",i,x);
\r
59 int selecttbl[8*256];
\r
60 static int selecttbl_init = 0;
\r
61 static void prbin(unsigned int x)
\r
64 // for(i = 31; i >= 0; i--){
\r
65 for (i = 0 ; i < 32; i ++) {
\r
66 fprintf(stderr,"%.1u", (x >> i)&1);
\r
68 fprintf(stderr, " ");
\r
72 int clz(unsigned int x)
\r
80 static void make_selecttbl(void)
\r
85 if (selecttbl_init) return;
\r
89 for (x = 0; x < 256; x++) {
\r
90 bp_setbits(buf,0,8,x);
\r
91 for (r=0; r<8; r++) selecttbl[(r<<8)+x] = -1;
\r
93 for (i=0; i<8; i++) {
\r
94 if (bp_getbit(buf,i)) {
\r
95 // fprintf(stderr, "Init: setting %i to %i (r= %i, x = %i)\n", (r<<8)+x, i, r, x);
\r
96 selecttbl[(r<<8)+x] = i;
\r
102 fprintf(stderr, "Select table:\n");
\r
103 for (i = 0; i < 8 * 256; i++){
\r
104 mask = i / 256 + 1;
\r
105 x = __builtin_clz((i + (i << 8)));
\r
107 fprintf(stderr, " (%.4i): %08i, %08i\n", i, selecttbl[i], x);
\r
113 darray * bp_darray_construct(int n, pb *buf, int opt)
\r
120 int p1,p2,p3,p4,s1,s2,s3,s4;
\r
131 printf("ERROR: L=%d LLL=%d\n",L,LLL);
\r
136 for (i=0; i<n; i++) m += bp_getbit(buf,i);
\r
139 //printf("n=%d m=%d\n",n,m);
\r
143 if (opt & (~OPT_NO_RANK)) { // construct select table
\r
145 nl = (m-1) / L + 1;
\r
146 bp_xmalloc(da->lp, nl+1);
\r
147 da->idx_size += (nl+1) * sizeof(*da->lp);
\r
148 bp_xmalloc(da->p, nl+1);
\r
149 da->idx_size += (nl+1) * sizeof(*da->p);
\r
151 for (r = 0; r < 2; r++) {
\r
152 s1 = s2 = s3 = s4 = 0;
\r
153 p1 = p2 = p3 = p4 = -1;
\r
156 for (il = 0; il < nl; il++) {
\r
158 while (s1 <= il*L) {
\r
159 if (bp_getbit(buf,p1+1)) s1++;
\r
164 i = min((il+1)*L-1,m-1);
\r
167 if (bp_getbit(buf,p2+1)) s2++;
\r
172 if (p - pp >= LL) {
\r
174 for (is = 0; is < L; is++) {
\r
175 if (il*L+is >= m) break;
\r
177 while (s3 <= il*L+is) {
\r
178 if (bp_getbit(buf,p3+1)) s3++;
\r
181 da->sl[ml*L+is] = p3;
\r
184 da->p[il] = -(ml+1);
\r
188 for (is = 0; is < L/LLL; is++) {
\r
189 if (il*L+is*LLL >= m) break;
\r
190 while (s4 <= il*L+is*LLL) {
\r
191 if (bp_getbit(buf,p4+1)) s4++;
\r
195 da->ss[ms*(L/LLL)+is] = p4 - pp;
\r
203 bp_xmalloc(da->sl,ml*L+1);
\r
204 da->idx_size += (ml*L+1) * sizeof(*da->sl);
\r
205 bp_xmalloc(da->ss, ms*(L/LLL)+1);
\r
206 da->idx_size += (ms*(L/LLL)+1) * sizeof(*da->ss);
\r
210 } else { // no select table
\r
212 da->p = da->sl = NULL;
\r
216 // construct rank table
\r
218 if ((opt & OPT_NO_RANK) == 0) {
\r
219 bp_xmalloc(da->rl,n/R1+2);
\r
220 da->idx_size += (n/R1+2) * sizeof(*da->rl);
\r
221 bp_xmalloc(da->rm,n/RR+2);
\r
223 da->idx_size += (n/RR+2) * sizeof(*da->rm);
\r
225 bp_xmalloc(da->rs,n/RRR+2);
\r
226 da->idx_size += (n/RRR+2) * sizeof(*da->rs);
\r
229 for (k=0; k<=n; k+=R1) {
\r
232 for (i=0; i<R1; i+=RR) {
\r
233 if (k+i <= n) da->rm[(k+i)/RR] = m2;
\r
235 for (j=0; j<RR; j++) {
\r
236 if (k+i+j < n && bp_getbit(buf,k+i+j)==1) m++;
\r
237 if (j % RRR == RRR-1) {
\r
238 if (k+i+j <= n) da->rs[(k+i+j)/RRR] = m;
\r
255 void bp_darray_free(darray *da) {
\r
258 if (da->buf) bp_free(da->buf);
\r
259 if (da->lp) bp_free(da->lp);
\r
260 if (da->sl) bp_free(da->sl);
\r
261 if (da->ss) bp_free(da->ss);
\r
262 if (da->p) bp_free(da->p);
\r
263 if (da->rl) bp_free(da->rl);
\r
264 if (da->rm) bp_free(da->rm);
\r
265 if (da->rs) bp_free(da->rs);
\r
270 static int darray_rank0(darray *da, int i)
\r
276 r = da->rl[i>>logR] + da->rm[i>>logRR] + da->rs[i>>logRRR];
\r
277 p = da->buf + ((i>>logRRR)<<(logRRR-logD));
\r
279 if (j < D) r += popcount(*p >> (D-1-j));
\r
280 else r += popcount(*p) + popcount(p[1] >> (D-1-(j-D)));
\r
285 r = da->rl[i>>logR] + da->rm[i>>logRR] + da->rs[i>>logRRR];
\r
286 p = da->buf + ((i>>logRRR)<<(logRRR-logD));
\r
288 r += popcount(*p++);
\r
291 r += popcount(*p >> (D-1-j));
\r
293 j = RRR-1 - (i & (RRR-1));
\r
295 r = da->rl[i>>logR] + da->rm[i>>logRR] + da->rs[i>>logRRR];
\r
296 p = da->buf + ((i>>logRRR)<<(logRRR-logD));
\r
298 r -= popcount(*--p);
\r
301 if (j > 0) r -= popcount(*--p << (D-j));
\r
309 int bp_darray_select_bsearch(darray *da, int i, pb (*getpat)(pb *))
\r
318 if (i == 0) return -1;
\r
332 l = 0; r = (n-1)>>logR;
\r
333 // find the smallest index x s.t. rl[x] >= t
\r
336 //printf("m=%d rl[m+1]=%d t=%d\n",m,da->rl[m+1],t);
\r
337 if (da->rl[m+1] > t) { // m+1 is out of range
\r
338 r = m; // new r = m >= l
\r
340 l = m+1; // new l = m+1 <= r
\r
348 l = x >> logRR; r = (min(x+R1-1,n))>>logRR;
\r
351 //printf("m=%d rm[m+1]=%d t=%d\n",m,da->rm[m+1],t);
\r
352 if (da->rm[m+1] > t) { // m+1 is out of range
\r
355 l = m+1; // new l = m+1 <= r
\r
364 l = x >> logRRR; r = (min(x+RR-1,n))>>logRRR;
\r
367 //printf("m=%d rs[m+1]=%d t=%d\n",m,da->rs[m+1],t);
\r
368 if (da->rs[m+1] > t) { // m+1 is out of range
\r
371 l = m+1; // new l = m+1 <= r
\r
378 while (t > da->rs[l]) {
\r
387 p = &da->buf[x >> logD];
\r
389 m = popcount(getpat(p));
\r
398 rr = popcount8(w >> (D-8));
\r
404 x += selecttbl[((t-0)<<8)+(w>>(D-8))];
\r
408 printf("error x=%d s=%d\n",x,s);
\r
414 int bp_darray_pat_rank(darray *da, int i, pb (*getpat)(pb *))
\r
419 r = da->rl[i>>logR] + da->rm[i>>logRR];
\r
420 j = (i>>logRRR) & (RR/RRR-1);
\r
422 r += da->rs[((i>>logRR)<<(logRR-logRRR))+j-1];
\r
426 p = da->buf + ((i>>logRRR)<<(logRRR-logD));
\r
429 r += popcount(getpat(p));
\r
433 r += popcount(getpat(p) >> (D-1-j));
\r
439 int bp_darray_select(darray *da, int i,int f)
\r
447 if (i <= 0 || i > da->m) return -1;
\r
451 il = da->p[ i >> logL ];
\r
454 p = da->sl[(il<<logL)+(i & (L-1))];
\r
456 p = da->lp[i>>logL];
\r
457 p += da->ss[(il<<(logL-logLLL))+(i & (L-1))/LLL];
\r
458 r = i - (i & (LLL-1));
\r
460 q = &(da->buf[p>>logD]);
\r
464 r -= popcount(*q >> (D-1-rr));
\r
469 if (r + rr >= i) break;
\r
477 //rr = popcount(x >> (D-8));
\r
478 //rr = popcount(x >> (D-8));
\r
479 rr = popcount8(x >> (D-8));
\r
480 if (r + rr >= i) break;
\r
485 p += selecttbl[((i-r-1)<<8)+(x>>(D-8))];
\r
488 r -= popcount((~(*q)) >> (D-1-rr));
\r
492 rr = popcount(~(*q));
\r
493 if (r + rr >= i) break;
\r
502 rr = popcount8(x >> (D-8));
\r
503 if (r + rr >= i) break;
\r
508 p += selecttbl[((i-r-1)<<8)+(x>>(D-8))];
\r
514 int bp_darray_pat_select(darray *da, int i, pb (*getpat)(pb *))
\r
522 if (i == 0) return -1;
\r
526 //printf("ERROR: m=%d i=%d\n",da->m,i);
\r
532 il = da->p[i>>logL];
\r
535 p = da->sl[(il<<logL)+(i & (L-1))];
\r
537 p = da->lp[i>>logL];
\r
538 p += da->ss[(il<<(logL-logLLL))+(i & (L-1))/LLL];
\r
539 r = i - (i & (LLL-1));
\r
541 q = &(da->buf[p>>logD]);
\r
544 r -= popcount(getpat(q) >> (D-1-rr));
\r
548 rr = popcount(getpat(q));
\r
549 if (r + rr >= i) break;
\r
557 rr = popcount8(x >> (D-8));
\r
558 if (r + rr >= i) break;
\r
563 p += selecttbl[((i-r-1)<<8)+(x>>(D-8))];
\r
569 darray * bp_darray_pat_construct(int n, pb *buf, int k, pb pat, int opt)
\r
575 bp_xmalloc(b, (n+D-1)/D);
\r
577 for (i=0; i<n-k+1; i++) {
\r
578 bp_setbit(b, i, getpattern(buf,i,k,pat));
\r
580 for (i=n-k+1; i<n; i++) {
\r
581 bp_setbit(b, i, 0);
\r
584 da = bp_darray_construct(n, b, opt);
\r