6 //typedef unsigned char byte;
\r
7 //typedef unsigned short word;
\r
8 //typedef unsigned int dword;
\r
13 #define PBS (sizeof(pb)*8)
\r
19 #define logLL 16 // size of word
\r
20 #define LL (1<<logLL)
\r
23 #define LLL (1<<logLLL)
\r
25 //#define logL (logLL-3)
\r
26 #define logL (logLL-1-5)
\r
30 #define min(x,y) ((x)<(y)?(x):(y))
\r
33 #define mymalloc(p,n,f) {p = (__typeof__(p)) malloc((n)*sizeof(*p)); if ((p)==NULL) {printf("not enough memory\n"); exit(1);}}
\r
35 int setbit(pb *B, int i,int x)
\r
41 if (x==0) B[j] &= (~(1<<(D-1-l)));
\r
42 else if (x==1) B[j] |= (1<<(D-1-l));
\r
44 printf("error setbit x=%d\n",x);
\r
50 int setbit_zero(pb *B, int i)
\r
55 B[j] &= (~(1<<(D-1-l)));
\r
59 int setbit_one(pb *B, int i)
\r
64 B[j] |= (1<<(D-1-l));
\r
71 int setbits(pb *B, int i, int d, int x)
\r
75 for (j=0; j<d; j++) {
\r
76 setbit(B,i+j,(x>>(d-j-1))&1);
\r
81 int getbit(pb *B, int i)
\r
89 return (B[j] >> (D-1-l)) & 1;
\r
92 dword getbits(pb *B, int i, int d)
\r
97 for (j=0; j<d; j++) {
\r
104 int getpattern(pb *B, int i, int k, pb pat)
\r
109 for (j=0; j<k; j++) {
\r
110 x &= getbit(B,i+j) ^ (~(pat>>(k-1-j)));
\r
112 //printf("getpattern(%d) = %d\n",i,x);
\r
117 static const unsigned int popCount[] = {
\r
118 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,
\r
119 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
\r
120 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
\r
121 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
\r
122 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
\r
123 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
\r
124 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
\r
125 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
\r
126 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
\r
127 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
\r
128 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
\r
129 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
\r
130 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
\r
131 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
\r
132 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
\r
133 4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8
\r
136 static int selecttbl[8*256];
\r
138 void make_selecttbl(void)
\r
143 for (x = 0; x < 256; x++) {
\r
144 setbits(buf,0,8,x);
\r
145 for (r=0; r<8; r++) selecttbl[(r<<8)+x] = -1;
\r
147 for (i=0; i<8; i++) {
\r
148 if (getbit(buf,i)) {
\r
149 selecttbl[(r<<8)+x] = i;
\r
157 int darray_construct(darray *da, int n, pb *buf, int opt)
\r
165 int p1,p2,p3,p4,s1,s2,s3,s4;
\r
173 printf("ERROR: L=%d LLL=%d\n",L,LLL);
\r
178 for (i=0; i<n; i++) m += getbit(buf,i);
\r
181 //printf("n=%d m=%d\n",n,m);
\r
185 if (opt & (~OPT_NO_RANK)) { // construct select table
\r
189 for (i=0; i<n; i++) {
\r
190 if (getbit(buf,i)) {
\r
196 nl = (m-1) / L + 1;
\r
197 mymalloc(da->lp,nl+1,1); da->idx_size += (nl+1)*sizeof(*da->lp);
\r
198 mymalloc(da->p,nl+1,1); da->idx_size += (nl+1)*sizeof(*da->p);
\r
200 printf("lp table: %d bytes (%1.2f bpc)\n",(nl+1)*sizeof(*da->lp), (double)(nl+1)*sizeof(*da->lp) * 8/n);
\r
201 printf("p table: %d bytes (%1.2f bpc)\n",(nl+1)*sizeof(*da->p), (double)(nl+1)*sizeof(*da->p) * 8/n);
\r
204 for (r = 0; r < 2; r++) {
\r
205 s1 = s2 = s3 = s4 = 0;
\r
206 p1 = p2 = p3 = p4 = -1;
\r
209 for (il = 0; il < nl; il++) {
\r
211 while (s1 <= il*L) {
\r
212 if (getbit(buf,p1+1)) s1++;
\r
217 i = min((il+1)*L-1,m-1);
\r
220 if (getbit(buf,p2+1)) s2++;
\r
224 //printf("%d ",p-pp);
\r
225 if (p - pp >= LL) {
\r
227 for (is = 0; is < L; is++) {
\r
228 if (il*L+is >= m) break;
\r
229 //da->sl[ml*L+is] = s[il*L+is];
\r
230 while (s3 <= il*L+is) {
\r
231 if (getbit(buf,p3+1)) s3++;
\r
234 da->sl[ml*L+is] = p3;
\r
237 da->p[il] = -(ml+1);
\r
241 for (is = 0; is < L/LLL; is++) {
\r
242 if (il*L+is*LLL >= m) break;
\r
243 while (s4 <= il*L+is*LLL) {
\r
244 if (getbit(buf,p4+1)) s4++;
\r
247 //da->ss[ms*(L/LLL)+is] = s[il*L+is*LLL] - pp;
\r
248 da->ss[ms*(L/LLL)+is] = p4 - pp;
\r
256 mymalloc(da->sl,ml*L+1,1); da->idx_size += (ml*L+1)*sizeof(*da->sl);
\r
257 mymalloc(da->ss,ms*(L/LLL)+1,1); da->idx_size += (ms*(L/LLL)+1)*sizeof(*da->ss);
\r
259 printf("sl table: %d bytes (%1.2f bpc)\n",(ml*L+1)*sizeof(*da->sl), (double)(ml*L+1)*sizeof(*da->sl) * 8/n);
\r
260 printf("ss table: %d bytes (%1.2f bpc)\n",(ms*(L/LLL)+1)*sizeof(*da->ss), (double)(ms*(L/LLL)+1)*sizeof(*da->ss) * 8/n);
\r
265 } else { // no select table
\r
267 da->p = da->sl = NULL;
\r
271 // construct rank table
\r
273 if ((opt & OPT_NO_RANK) == 0) {
\r
274 mymalloc(da->rl,n/R1+2,1); da->idx_size += (n/R1+2)*sizeof(*da->rl);
\r
275 mymalloc(da->rm,n/RR+2,1); da->idx_size += (n/RR+2)*sizeof(*da->rm);
\r
276 mymalloc(da->rs,n/RRR+2,1); da->idx_size += (n/RRR+2)*sizeof(*da->rs);
\r
278 printf("rl table: %d bytes (%1.2f bpc)\n",(n/R1+2)*sizeof(*da->rl), (double)(n/R1+2)*sizeof(*da->rl) * 8/n);
\r
279 printf("rm table: %d bytes (%1.2f bpc)\n",(n/RR+2)*sizeof(*da->rm), (double)(n/RR+2)*sizeof(*da->rm) * 8/n);
\r
280 printf("rs table: %d bytes (%1.2f bpc)\n",(n/RRR+2)*sizeof(*da->rs), (double)(n/RRR+2)*sizeof(*da->rs) * 8/n);
\r
283 for (k=0; k<=n; k+=R1) {
\r
286 for (i=0; i<R1; i+=RR) {
\r
287 if (k+i <= n) da->rm[(k+i)/RR] = m2;
\r
289 for (j=0; j<RR; j++) {
\r
290 if (k+i+j < n && getbit(buf,k+i+j)==1) m++;
\r
291 if (j % RRR == RRR-1) {
\r
292 if (k+i+j <= n) da->rs[(k+i+j)/RRR] = m;
\r
309 // destroyDarray: frees the memory of darray
\r
310 // Added by Diego Arroyuelo
\r
311 void destroyDarray(darray *da) {
\r
312 if (!da) return; // nothing to free
\r
314 if (da->buf) free(da->buf);
\r
315 if (da->lp) free(da->lp);
\r
316 if (da->sl) free(da->sl);
\r
317 if (da->ss) free(da->ss);
\r
318 if (da->p) free(da->p);
\r
319 if (da->rl) free(da->rl);
\r
320 if (da->rm) free(da->rm);
\r
321 if (da->rs) free(da->rs);
\r
324 int darray_rank0(darray *da, int i)
\r
330 r = da->rl[i>>logR] + da->rm[i>>logRR] + da->rs[i>>logRRR];
\r
331 p = da->buf + ((i>>logRRR)<<(logRRR-logD));
\r
333 if (j < D) r += popcount(*p >> (D-1-j));
\r
334 else r += popcount(*p) + popcount(p[1] >> (D-1-(j-D)));
\r
339 r = da->rl[i>>logR] + da->rm[i>>logRR] + da->rs[i>>logRRR];
\r
340 p = da->buf + ((i>>logRRR)<<(logRRR-logD));
\r
342 r += popcount(*p++);
\r
345 r += popcount(*p >> (D-1-j));
\r
347 j = RRR-1 - (i & (RRR-1));
\r
349 r = da->rl[i>>logR] + da->rm[i>>logRR] + da->rs[i>>logRRR];
\r
350 p = da->buf + ((i>>logRRR)<<(logRRR-logD));
\r
352 r -= popcount(*--p);
\r
355 if (j > 0) r -= popcount(*--p << (D-j));
\r
363 int darray_rank(darray *da, int i)
\r
365 int r,j,i_rr, i_rrr;
\r
368 i_rrr = i >> logRRR;
\r
369 r = da->rl[i>>logR] + da->rm[i_rr];
\r
371 j = (i_rrr) & (RR/RRR-1);
\r
373 r += da->rs[((i_rr)<<(logRR-logRRR))+j-1];
\r
377 p = da->buf + ((i_rrr)<<(logRRR-logD));
\r
380 r += popcount(*p++);
\r
383 r += popcount(*p >> (D-1-j));
\r
388 int darray_select_bsearch(darray *da, int i, pb (*getpat)(pb *))
\r
397 //s = darray_select(da,i,1);
\r
399 //printf("select(%d)=%d\n",i,s);
\r
403 if (i == 0) return -1;
\r
417 l = 0; r = (n-1)>>logR;
\r
418 // find the smallest index x s.t. rl[x] >= t
\r
421 //printf("m=%d rl[m+1]=%d t=%d\n",m,da->rl[m+1],t);
\r
422 if (da->rl[m+1] > t) { // m+1 is out of range
\r
423 r = m; // new r = m >= l
\r
425 l = m+1; // new l = m+1 <= r
\r
433 l = x >> logRR; r = (min(x+R1-1,n))>>logRR;
\r
436 //printf("m=%d rm[m+1]=%d t=%d\n",m,da->rm[m+1],t);
\r
437 if (da->rm[m+1] > t) { // m+1 is out of range
\r
440 l = m+1; // new l = m+1 <= r
\r
449 l = x >> logRRR; r = (min(x+RR-1,n))>>logRRR;
\r
452 //printf("m=%d rs[m+1]=%d t=%d\n",m,da->rs[m+1],t);
\r
453 if (da->rs[m+1] > t) { // m+1 is out of range
\r
456 l = m+1; // new l = m+1 <= r
\r
463 while (t > da->rs[l]) {
\r
472 p = &da->buf[x >> logD];
\r
474 m = popcount(getpat(p));
\r
483 rr = popCount[w >> (D-8)];
\r
489 x += selecttbl[((t-0)<<8)+(w>>(D-8))];
\r
493 printf("error x=%d s=%d\n",x,s);
\r
499 int darray_pat_rank(darray *da, int i, pb (*getpat)(pb *))
\r
504 r = da->rl[i>>logR] + da->rm[i>>logRR];
\r
505 j = (i>>logRRR) & (RR/RRR-1);
\r
507 r += da->rs[((i>>logRR)<<(logRR-logRRR))+j-1];
\r
511 p = da->buf + ((i>>logRRR)<<(logRRR-logD));
\r
514 r += popcount(getpat(p));
\r
518 r += popcount(getpat(p) >> (D-1-j));
\r
524 int darray_select(darray *da, int i,int f)
\r
532 if (i == 0) return -1;
\r
536 //printf("ERROR: m=%d i=%d\n",da->m,i);
\r
542 il = da->p[i>>logL];
\r
545 p = da->sl[(il<<logL)+(i & (L-1))];
\r
547 p = da->lp[i>>logL];
\r
548 p += da->ss[(il<<(logL-logLLL))+(i & (L-1))/LLL];
\r
549 r = i - (i & (LLL-1));
\r
551 q = &(da->buf[p>>logD]);
\r
555 r -= popcount(*q >> (D-1-rr));
\r
560 if (r + rr >= i) break;
\r
568 //rr = popcount(x >> (D-8));
\r
569 //rr = popcount(x >> (D-8));
\r
570 rr = popcount8(x >> (D-8));
\r
571 if (r + rr >= i) break;
\r
576 p += selecttbl[((i-r-1)<<8)+(x>>(D-8))];
\r
579 r -= popcount((~(*q)) >> (D-1-rr));
\r
583 rr = popcount(~(*q));
\r
584 if (r + rr >= i) break;
\r
593 //rr = popcount(x >> (D-8));
\r
594 //rr = popCount[x >> (D-8)];
\r
595 rr = popcount8(x >> (D-8));
\r
596 if (r + rr >= i) break;
\r
601 p += selecttbl[((i-r-1)<<8)+(x>>(D-8))];
\r
607 int darray_pat_select(darray *da, int i, pb (*getpat)(pb *))
\r
615 if (i == 0) return -1;
\r
619 //printf("ERROR: m=%d i=%d\n",da->m,i);
\r
625 il = da->p[i>>logL];
\r
628 p = da->sl[(il<<logL)+(i & (L-1))];
\r
630 p = da->lp[i>>logL];
\r
631 p += da->ss[(il<<(logL-logLLL))+(i & (L-1))/LLL];
\r
632 r = i - (i & (LLL-1));
\r
634 q = &(da->buf[p>>logD]);
\r
637 r -= popcount(getpat(q) >> (D-1-rr));
\r
641 rr = popcount(getpat(q));
\r
642 if (r + rr >= i) break;
\r
650 //rr = popcount(x >> (D-8));
\r
651 //rr = popCount[x >> (D-8)];
\r
652 rr = popcount8(x >> (D-8));
\r
653 if (r + rr >= i) break;
\r
658 p += selecttbl[((i-r-1)<<8)+(x>>(D-8))];
\r
663 int darray_pat_construct(darray *da, int n, pb *buf, int k, pb pat, int opt)
\r
667 mymalloc(b,(n+D-1)/D,0);
\r
669 for (i=0; i<n-k+1; i++) {
\r
670 setbit(b,i,getpattern(buf,i,k,pat));
\r
672 for (i=n-k+1; i<n; i++) {
\r
676 darray_construct(da,n,b,opt);
\r