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 static int selecttbl[8*256];
\r
60 static int selecttbl_init = 0;
\r
62 static void make_selecttbl(void)
\r
66 if (selecttbl_init) return;
\r
70 for (x = 0; x < 256; x++) {
\r
71 bp_setbits(buf,0,8,x);
\r
72 for (r=0; r<8; r++) selecttbl[(r<<8)+x] = -1;
\r
74 for (i=0; i<8; i++) {
\r
75 if (bp_getbit(buf,i)) {
\r
76 selecttbl[(r<<8)+x] = i;
\r
84 darray * bp_darray_construct(int n, pb *buf, int opt)
\r
91 int p1,p2,p3,p4,s1,s2,s3,s4;
\r
102 printf("ERROR: L=%d LLL=%d\n",L,LLL);
\r
107 for (i=0; i<n; i++) m += bp_getbit(buf,i);
\r
110 //printf("n=%d m=%d\n",n,m);
\r
114 if (opt & (~OPT_NO_RANK)) { // construct select table
\r
116 nl = (m-1) / L + 1;
\r
117 bp_xmalloc(da->lp, nl+1);
\r
118 da->idx_size += (nl+1) * sizeof(*da->lp);
\r
119 bp_xmalloc(da->p, nl+1);
\r
120 da->idx_size += (nl+1) * sizeof(*da->p);
\r
122 for (r = 0; r < 2; r++) {
\r
123 s1 = s2 = s3 = s4 = 0;
\r
124 p1 = p2 = p3 = p4 = -1;
\r
127 for (il = 0; il < nl; il++) {
\r
129 while (s1 <= il*L) {
\r
130 if (bp_getbit(buf,p1+1)) s1++;
\r
135 i = min((il+1)*L-1,m-1);
\r
138 if (bp_getbit(buf,p2+1)) s2++;
\r
143 if (p - pp >= LL) {
\r
145 for (is = 0; is < L; is++) {
\r
146 if (il*L+is >= m) break;
\r
148 while (s3 <= il*L+is) {
\r
149 if (bp_getbit(buf,p3+1)) s3++;
\r
152 da->sl[ml*L+is] = p3;
\r
155 da->p[il] = -(ml+1);
\r
159 for (is = 0; is < L/LLL; is++) {
\r
160 if (il*L+is*LLL >= m) break;
\r
161 while (s4 <= il*L+is*LLL) {
\r
162 if (bp_getbit(buf,p4+1)) s4++;
\r
166 da->ss[ms*(L/LLL)+is] = p4 - pp;
\r
174 bp_xmalloc(da->sl,ml*L+1);
\r
175 da->idx_size += (ml*L+1) * sizeof(*da->sl);
\r
176 bp_xmalloc(da->ss, ms*(L/LLL)+1);
\r
177 da->idx_size += (ms*(L/LLL)+1) * sizeof(*da->ss);
\r
181 } else { // no select table
\r
183 da->p = da->sl = NULL;
\r
187 // construct rank table
\r
189 if ((opt & OPT_NO_RANK) == 0) {
\r
190 bp_xmalloc(da->rl,n/R1+2);
\r
191 da->idx_size += (n/R1+2) * sizeof(*da->rl);
\r
192 bp_xmalloc(da->rm,n/RR+2);
\r
194 da->idx_size += (n/RR+2) * sizeof(*da->rm);
\r
196 bp_xmalloc(da->rs,n/RRR+2);
\r
197 da->idx_size += (n/RRR+2) * sizeof(*da->rs);
\r
200 for (k=0; k<=n; k+=R1) {
\r
203 for (i=0; i<R1; i+=RR) {
\r
204 if (k+i <= n) da->rm[(k+i)/RR] = m2;
\r
206 for (j=0; j<RR; j++) {
\r
207 if (k+i+j < n && bp_getbit(buf,k+i+j)==1) m++;
\r
208 if (j % RRR == RRR-1) {
\r
209 if (k+i+j <= n) da->rs[(k+i+j)/RRR] = m;
\r
226 void bp_darray_free(darray *da) {
\r
229 if (da->buf) bp_free(da->buf);
\r
230 if (da->lp) bp_free(da->lp);
\r
231 if (da->sl) bp_free(da->sl);
\r
232 if (da->ss) bp_free(da->ss);
\r
233 if (da->p) bp_free(da->p);
\r
234 if (da->rl) bp_free(da->rl);
\r
235 if (da->rm) bp_free(da->rm);
\r
236 if (da->rs) bp_free(da->rs);
\r
241 static int darray_rank0(darray *da, int i)
\r
247 r = da->rl[i>>logR] + da->rm[i>>logRR] + da->rs[i>>logRRR];
\r
248 p = da->buf + ((i>>logRRR)<<(logRRR-logD));
\r
250 if (j < D) r += popcount(*p >> (D-1-j));
\r
251 else r += popcount(*p) + popcount(p[1] >> (D-1-(j-D)));
\r
256 r = da->rl[i>>logR] + da->rm[i>>logRR] + da->rs[i>>logRRR];
\r
257 p = da->buf + ((i>>logRRR)<<(logRRR-logD));
\r
259 r += popcount(*p++);
\r
262 r += popcount(*p >> (D-1-j));
\r
264 j = RRR-1 - (i & (RRR-1));
\r
266 r = da->rl[i>>logR] + da->rm[i>>logRR] + da->rs[i>>logRRR];
\r
267 p = da->buf + ((i>>logRRR)<<(logRRR-logD));
\r
269 r -= popcount(*--p);
\r
272 if (j > 0) r -= popcount(*--p << (D-j));
\r
280 int bp_darray_select_bsearch(darray *da, int i, pb (*getpat)(pb *))
\r
289 if (i == 0) return -1;
\r
303 l = 0; r = (n-1)>>logR;
\r
304 // find the smallest index x s.t. rl[x] >= t
\r
307 //printf("m=%d rl[m+1]=%d t=%d\n",m,da->rl[m+1],t);
\r
308 if (da->rl[m+1] > t) { // m+1 is out of range
\r
309 r = m; // new r = m >= l
\r
311 l = m+1; // new l = m+1 <= r
\r
319 l = x >> logRR; r = (min(x+R1-1,n))>>logRR;
\r
322 //printf("m=%d rm[m+1]=%d t=%d\n",m,da->rm[m+1],t);
\r
323 if (da->rm[m+1] > t) { // m+1 is out of range
\r
326 l = m+1; // new l = m+1 <= r
\r
335 l = x >> logRRR; r = (min(x+RR-1,n))>>logRRR;
\r
338 //printf("m=%d rs[m+1]=%d t=%d\n",m,da->rs[m+1],t);
\r
339 if (da->rs[m+1] > t) { // m+1 is out of range
\r
342 l = m+1; // new l = m+1 <= r
\r
349 while (t > da->rs[l]) {
\r
358 p = &da->buf[x >> logD];
\r
360 m = popcount(getpat(p));
\r
369 rr = popcount8(w >> (D-8));
\r
375 x += selecttbl[((t-0)<<8)+(w>>(D-8))];
\r
379 printf("error x=%d s=%d\n",x,s);
\r
385 int bp_darray_pat_rank(darray *da, int i, pb (*getpat)(pb *))
\r
390 r = da->rl[i>>logR] + da->rm[i>>logRR];
\r
391 j = (i>>logRRR) & (RR/RRR-1);
\r
393 r += da->rs[((i>>logRR)<<(logRR-logRRR))+j-1];
\r
397 p = da->buf + ((i>>logRRR)<<(logRRR-logD));
\r
400 r += popcount(getpat(p));
\r
404 r += popcount(getpat(p) >> (D-1-j));
\r
410 int bp_darray_select(darray *da, int i,int f)
\r
418 if (i <= 0 || i > da->m) return -1;
\r
422 il = da->p[ i >> logL ];
\r
425 p = da->sl[(il<<logL)+(i & (L-1))];
\r
427 p = da->lp[i>>logL];
\r
428 p += da->ss[(il<<(logL-logLLL))+(i & (L-1))/LLL];
\r
429 r = i - (i & (LLL-1));
\r
431 q = &(da->buf[p>>logD]);
\r
435 r -= popcount(*q >> (D-1-rr));
\r
440 if (r + rr >= i) break;
\r
448 //rr = popcount(x >> (D-8));
\r
449 //rr = popcount(x >> (D-8));
\r
450 rr = popcount8(x >> (D-8));
\r
451 if (r + rr >= i) break;
\r
456 p += selecttbl[((i-r-1)<<8)+(x>>(D-8))];
\r
459 r -= popcount((~(*q)) >> (D-1-rr));
\r
463 rr = popcount(~(*q));
\r
464 if (r + rr >= i) break;
\r
473 rr = popcount8(x >> (D-8));
\r
474 if (r + rr >= i) break;
\r
479 p += selecttbl[((i-r-1)<<8)+(x>>(D-8))];
\r
485 int bp_darray_pat_select(darray *da, int i, pb (*getpat)(pb *))
\r
493 if (i == 0) return -1;
\r
497 //printf("ERROR: m=%d i=%d\n",da->m,i);
\r
503 il = da->p[i>>logL];
\r
506 p = da->sl[(il<<logL)+(i & (L-1))];
\r
508 p = da->lp[i>>logL];
\r
509 p += da->ss[(il<<(logL-logLLL))+(i & (L-1))/LLL];
\r
510 r = i - (i & (LLL-1));
\r
512 q = &(da->buf[p>>logD]);
\r
515 r -= popcount(getpat(q) >> (D-1-rr));
\r
519 rr = popcount(getpat(q));
\r
520 if (r + rr >= i) break;
\r
528 rr = popcount8(x >> (D-8));
\r
529 if (r + rr >= i) break;
\r
534 p += selecttbl[((i-r-1)<<8)+(x>>(D-8))];
\r
540 darray * bp_darray_pat_construct(int n, pb *buf, int k, pb pat, int opt)
\r
546 bp_xmalloc(b, (n+D-1)/D);
\r
548 for (i=0; i<n-k+1; i++) {
\r
549 bp_setbit(b, i, getpattern(buf,i,k,pat));
\r
551 for (i=n-k+1; i<n; i++) {
\r
552 bp_setbit(b, i, 0);
\r
555 da = bp_darray_construct(n, b, opt);
\r