6 typedef unsigned int qword;
9 typedef unsigned long long qword;
12 #define PBS (sizeof(uint)*8)
18 #define logLL 16 // size of word
24 #define LLL (1<<logLLL)
26 //#define logL (logLL-3)
27 #define logL (logLL-1-5)
41 int __setbit(uint *B, int i,int x) {
46 if (x==0) B[j] &= (~(1<<(D-1-l)));
47 else if (x==1) B[j] |= (1<<(D-1-l));
49 printf("error __setbit x=%d\n",x);
56 int __setbit2(uchar *B, int i,int x) {
61 if (x==0) B[j] &= (~(1<<(8-1-l)));
62 else if (x==1) B[j] |= (1<<(8-1-l));
64 printf("error __setbit2 x=%d\n",x);
71 int __setbits(uint *B, int i, int d, int x) {
75 __setbit(B,i+j,(x>>(d-j-1))&1);
81 int __getbit(uint *B, int i) {
88 return (B[j] >> (D-1-l)) & 1;
92 static int __getbit2(uchar *B, int i) {
99 return (B[j] >> (8-1-l)) & 1;
104 uint __getbits_aux(uint *B, int i, int d) {
109 if (d==8 && (j & 7) == 0) {
111 x = (uint) (((unsigned char*) B)[i]);
112 } else if (i+d <= 2*D) {
113 x = (((qword)B[0]) << D) + B[1];
119 fprintf(stderr, "Warning: %d, %d\n", D, d);
120 x = (((qword)B[0])<<D)+B[1];
123 x &= (((qword)1L<<D)-1)<<D;
133 static uint __getbits(uint *B, int i, int d)
138 x = ((uint64_t *) B)[0];
139 x = (x << 32)|(x >> 32);
140 x = (x << i) >> (2*D - d);
146 #if HAS_NATIVE_POPCOUNT
147 static inline unsigned int popcount(unsigned int n){
148 asm ("popcnt %1, %0" : "=r" (n) : "0" (n));
152 // static inline unsigned int popcount8(unsigned int n) {
153 // return __builtin_popcount(n & 0xff);
156 static inline unsigned int _fast_popcount(uchar x)
158 return __builtin_popcount(x);
163 static const unsigned int _popCount[] = {
164 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,
165 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
166 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
167 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
168 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
169 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
170 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
171 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
172 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
173 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
174 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
175 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
176 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
177 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
178 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
179 4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8
182 static inline unsigned int
183 _fast_popcount(int x) {
184 return _popCount[x & 0xff];
190 //static unsigned int __selecttbl[8*256];
191 static int built = 0;
193 void make___selecttbl(void) {
199 for (x = 0; x < 256; x++) {
200 __setbits(buf,0,8,x);
201 // for (r=0; r<8; r++) __selecttbl[(r<<8)+x] = -1;
203 for (i=0; i<8; i++) {
204 if (__getbit(buf,i)) {
205 // __selecttbl[(r<<8)+x] = i;
212 int selectd2_save(selectd2 * s, FILE * fp) {
214 wr += fwrite(&s->n,sizeof(uint),1,fp);
215 wr += fwrite(&s->m,sizeof(uint),1,fp);
216 wr += fwrite(&s->size,sizeof(uint),1,fp);
217 wr += fwrite(&s->ss_len,sizeof(uint),1,fp);
218 wr += fwrite(&s->sl_len,sizeof(uint),1,fp);
219 wr += fwrite(s->buf,sizeof(uchar),(s->n+7)/8+1,fp);
220 uint nl = (s->m-1) / L + 1;
221 wr += fwrite(s->lp,sizeof(uint),nl+1,fp);
222 wr += fwrite(s->p,sizeof(uint),nl+1,fp);
223 wr += fwrite(s->ss,sizeof(ushort),s->ss_len,fp);
224 wr += fwrite(s->sl,sizeof(uint),s->sl_len,fp);
225 if(wr!=s->sl_len+s->ss_len+2*(nl+1)+(s->n+7)/8+1+5)
231 int selectd2_load(selectd2 * s, FILE * fp) {
233 rd += fread(&s->n,sizeof(uint),1,fp);
234 rd += fread(&s->m,sizeof(uint),1,fp);
235 rd += fread(&s->size,sizeof(uint),1,fp);
236 rd += fread(&s->ss_len,sizeof(uint),1,fp);
237 rd += fread(&s->sl_len,sizeof(uint),1,fp);
238 s->buf = new uchar[(s->n+7)/8+1];
239 rd += fread(s->buf,sizeof(uchar),(s->n+7)/8+1,fp);
240 uint nl = (s->m-1) / L + 1;
241 s->lp = new uint[nl+1];
242 rd += fread(s->lp,sizeof(uint),nl+1,fp);
243 s->p = new uint[nl+1];
244 rd += fread(s->p,sizeof(uint),nl+1,fp);
245 s->ss = new ushort[s->ss_len];
246 rd += fread(s->ss,sizeof(ushort),s->ss_len,fp);
247 s->sl = new uint[s->sl_len];
248 rd += fread(s->sl,sizeof(uint),s->sl_len,fp);
249 if(rd!=s->sl_len+s->ss_len+2*(nl+1)+(s->n+7)/8+1+5)
255 void selectd2_free(selectd2 * s) {
264 int selectd2_construct(selectd2 *select, int n, uchar *buf) {
272 //make___selecttbl();
275 printf("ERROR: L=%d LLL=%d\n",L,LLL);
280 for (i=0; i<n; i++) m += __getbit2(buf,i);
283 //printf("n=%d m=%d\n",n,m);
289 for (i=0; i<n; i++) {
290 if (__getbit2(buf,i)) {
297 select->size = 0; //ignoring buf, shared with selects3
298 select->lp = new uint[nl+1];
299 for(int k=0;k<nl+1;k++) select->lp[k]=0;
300 select->size += (nl+1)*sizeof(uint);
301 select->p = new uint[nl+1];
302 for(int k=0;k<nl+1;k++) select->p[k]=0;
303 select->size += (nl+1)*sizeof(uint);
306 for (r = 0; r < 2; r++) {
308 for (il = 0; il < nl; il++) {
311 i = min((il+1)*L-1,m-1);
313 // printf("p-pp=%d, LL=%d\n",p-pp, LL);
317 for (is = 0; is < L; is++) {
318 if (il*L+is >= m) break;
319 select->sl[ml*L+is] = s[il*L+is];
323 select->p[il] = -((ml<<logL)+1);
328 for (is = 0; is < L/LLL; is++) {
329 if (il*L+is*LLL >= m) break;
330 select->ss[ms*(L/LLL)+is] = s[il*L+is*LLL] - pp;
333 select->p[il] = ms << (logL-logLLL);
339 select->sl = new uint[ml*L+1];
340 for(int k=0;k<ml*L+1;k++) select->sl[k]=0;
341 select->size += sizeof(uint)*(ml*L+1);
342 select->sl_len = ml*L+1;
343 select->ss = new ushort[ms*(L/LLL)+1];
344 for(int k=0;k<ms*(L/LLL)+1;k++) select->ss[k]=0;
345 select->ss_len = ms*(L/LLL)+1;
346 select->size += sizeof(ushort)*(ms*(L/LLL)+1);
354 int selectd2_select1(selectd2 *select, int i) {
359 if (i <= 0) return -1;
362 il = select->p[i>>logL];
365 //p = select->sl[(il<<logL)+(i & (L-1))];
366 p = select->sl[il+(i & (L-1))];
369 p = select->lp[i>>logL];
370 p += select->ss[il+((i & (L-1))>>logLLL)];
371 r = i - (i & (LLL-1));
373 q = &(select->buf[p>>3]);
376 r -= _fast_popcount(*q >> (8-1-rr));
379 //rr = _popCount[*q];
380 rr = _fast_popcount(*q);
381 if (r + rr >= i) break;
386 p = (q - select->buf) << 3;
387 p += selecttbl[((i-r-1)<<8)+(*q)];
392 int selectd2_select0(selectd2 *select, int i) {
398 if (i <= 0) return -1;
401 il = select->p[i>>logL];
404 return select->sl[il+(i & (L-1))];
407 p = select->lp[i>>logL];
409 p += select->ss[il+((i & (L-1))>>logLLL)];
410 r = i - (i & (LLL-1));
412 q = &(select->buf[p>>3]);
416 uint masked_q = *q ^ 0xff;
418 r -= _fast_popcount(masked_q >> (7-rr));
421 rr = _fast_popcount(masked_q);
423 p = (q - select->buf) << 3;
424 p += selecttbl[((i-r-1)<<8)+masked_q];
429 masked_q = *q ^ 0xff;
434 int selectd2_select(selectd2 *select, int i,int f) {
435 return f ? selectd2_select1(select, i) :
436 selectd2_select0(select, i);
440 int selectd2_select2(selectd2 *select, int i,int f, int *st, int *en) {
453 printf("ERROR: m=%d i=%d\n",select->m,i);
460 il = select->p[i>>logL];
463 //p = select->sl[(il<<logL)+(i & (L-1))];
464 p = select->sl[il+(i & (L-1))];
466 if ((i>>logL) == ((i+1)>>logL)) {
467 p2 = select->sl[il+((i+1) & (L-1))];
470 p2 = selectd2_select(select,i+2,f);
474 p = select->lp[i>>logL];
475 //p += select->ss[(il<<(logL-logLLL))+(i & (L-1))/LLL];
476 p += select->ss[il+((i & (L-1))>>logLLL)];
477 r = i - (i & (LLL-1));
479 q = &(select->buf[p>>3]);
483 //r -= _popCount[*q >> (8-1-rr)];
484 r -= _fast_popcount(*q >> (8-1-rr));
488 //rr = _popCount[*q];
489 rr = _fast_popcount(*q);
490 if (r + rr >= i) break;
495 p = (q - select->buf) << 3;
496 p += selecttbl[((i-r-1)<<8)+(*q)];
498 if ((i>>logL) == ((i+1)>>logL)) {
501 //rr = _popCount[*q];
502 r = _fast_popcount(*q);
503 if (r + rr >= i) break;
507 p2 = (q - select->buf) << 3;
508 p2 += selecttbl[((i-r-1)<<8)+(*q)];
511 p2 = selectd2_select(select,i+2,f);
517 //r -= _popCount[(*q ^ 0xff) >> (8-1-rr)];
518 r -= _fast_popcount((*q ^ 0xff) >> (8-1-rr));
522 //rr = _popCount[*q ^ 0xff];
523 rr = _fast_popcount(*q ^ 0xff);
524 if (r + rr >= i) break;
529 p = (q - select->buf) << 3;
530 p += selecttbl[((i-r-1)<<8)+(*q ^ 0xff)];
532 if ((i>>logL) == ((i+1)>>logL)) {
535 //rr = _popCount[*q ^ 0xff];
536 rr = _fast_popcount(*q ^ 0xff);
537 if (r + rr >= i) break;
541 p2 = (q - select->buf) << 3;
542 p2 += selecttbl[((i-r-1)<<8)+(*q ^ 0xff)];
545 p2 = selectd2_select(select,i+2,f);
555 int selects3_save(selects3 * s, FILE * fp) {
557 wr += fwrite(&s->n,sizeof(uint),1,fp);
558 wr += fwrite(&s->m,sizeof(uint),1,fp);
559 wr += fwrite(&s->size,sizeof(uint),1,fp);
560 wr += fwrite(&s->d,sizeof(uint),1,fp);
561 wr += fwrite(&s->hi_len,sizeof(uint),1,fp);
562 wr += fwrite(&s->low_len,sizeof(uint),1,fp);
563 wr += fwrite(s->hi,sizeof(uchar),s->hi_len,fp);
564 wr += fwrite(s->low,sizeof(uint),s->low_len,fp);
565 if(wr!=(6+s->hi_len+s->low_len))
567 if(selectd2_save(s->sd0,fp)) return 2;
568 if(selectd2_save(s->sd1,fp)) return 3;
573 int selects3_load(selects3 * s, FILE * fp) {
575 rd += fread(&s->n,sizeof(uint),1,fp);
576 rd += fread(&s->m,sizeof(uint),1,fp);
577 rd += fread(&s->size,sizeof(uint),1,fp);
578 rd += fread(&s->d,sizeof(uint),1,fp);
579 rd += fread(&s->hi_len,sizeof(uint),1,fp);
580 rd += fread(&s->low_len,sizeof(uint),1,fp);
581 s->hi = new uchar[s->hi_len];
582 rd += fread(s->hi,sizeof(uchar),s->hi_len,fp);
583 s->low = new uint[s->low_len];
584 rd += fread(s->low,sizeof(uint),s->low_len,fp);
585 if(rd!=(6+s->hi_len+s->low_len))
587 s->sd0 = new selectd2;
588 if(selectd2_load(s->sd0,fp)) return 2;
589 s->sd1 = new selectd2;
590 if(selectd2_load(s->sd1,fp)) return 3;
591 delete [] s->sd0->buf;
592 delete [] s->sd1->buf;
599 void selects3_free(selects3 * s) {
602 //delete [] s->sd0->buf;
603 selectd2_free(s->sd0);
605 selectd2_free(s->sd1);
610 int selects3_construct(selects3 *select, int n, uint *buf) {
618 for (i=0; i<n; i++) m += __getbit(buf,i);
622 if (m == 0) return 0;
633 buf2 = new uchar[(2*m+8-1)/8+1];
634 for(int k=0;k<(2*m+8-1)/8+1;k++) buf2[k]=0;
635 select->hi_len = (2*m+8-1)/8+1;
636 low = new uint[(d*m+PBS-1)/PBS+1];
637 for(uint k=0;k<(d*m+PBS-1)/PBS+1;k++) low[k]=0;
638 select->low_len = (d*m+PBS-1)/PBS+1;
642 select->size = sizeof(uchar)*((2*m+8-1)/8+1) + sizeof(uint)*((d*m+PBS-1)/PBS+1);
644 for (i=0; i<m*2; i++) __setbit2(buf2,i,0);
647 for (i=0; i<n; i++) {
648 if (__getbit(buf,i)) {
649 __setbit2(buf2,(i>>d)+m,1);
650 __setbits(low,m*d,d,i & ((1<<d)-1));
657 select->size += 2*sizeof(selectd2);
659 selectd2_construct(sd1,m*2,buf2);
662 for (i=0; i<m*2; i++) __setbit2(buf2,i,1-__getbit2(buf2,i));
663 selectd2_construct(sd0,m*2,buf2);
666 for (i=0; i<m*2; i++) __setbit2(buf2,i,1-__getbit2(buf2,i));
670 //selects3 * lasts3=NULL;
674 int selects3_select(selects3 *select, int i) {
679 printf("ERROR: m=%d i=%d\n",select->m,i);
684 if (i == 0) return -1;
687 /*if(select->lasti==(uint)i-1) {
688 while(!__getbit2(select->sd1->buf,++select->lasts));
691 select->lasts = selectd2_select(select->sd1,i,1);
694 //lasts3 = select; */
695 x = selectd2_select1(select->sd1,i) - (i-1);
696 //x = (select->lasts-(i-1)) << d;
698 x += __getbits(select->low,(i-1)*d,d);
702 void pr_byte(FILE* fp, uchar b)
705 for(int i = 0; i < 8; i++){
706 fprintf(stderr, "%i", __getbit2(buff, i));
710 int selects3_selectnext(selects3 *select, int i) {
711 //return selects3_select(select,selects3_rank(select,i)+1);
720 y = selectd2_select0(select->sd0,ii)+1;
730 if (((z << r) & 0x80) == 0) {
735 w = __getbits(q,xoffset,d);
738 if (__getbit2(select->hi,((y << 3)+r))) k2 ++;
749 if(__getbit2(select->hi,( (y << 3)+r))) k2++;
757 if(x==select->m) return (uint)-1;
762 uint mask = ~(0xffu << (8*sizeof(uint) - 8));
763 uint tmp = (select->hi[y] << ((8*sizeof(uint) - 8)+r)) | mask;
764 uint c_incr = __builtin_clz(tmp);
769 uchar * pp = &(select->hi[c >> 3]);
776 c += __builtin_clz(*pp) - 24;
781 return __getbits(q,xoffset,d)+((c)<<d);
784 int selects3_rank(selects3 *select, int i) {
796 y = selectd2_select0(select->sd0, ii)+1;
808 if (((z << r) & 0x80) == 0) return x;
810 w = __getbits(q, xoffset, d);
812 if (w >= j) return x + (w == j);