#include <sdarray.h>
+#include <stdint.h>
using std::min;
using std::max;
#if 0
return x;
}
-uint __getbits(uint *B, int i, int d)
+static uint __getbits(uint *B, int i, int d)
{
- ulong x;
-// uint y;
- // y = __getbits_aux(B, i,d);
+ uint64_t x;
B += (i >> logD);
i &= (D-1);
- x = ((ulong *) B)[0];
+ x = ((uint64_t *) B)[0];
x = (x << 32)|(x >> 32);
- x <<= i;
- x >>= 2*D - d;
-// fprintf(stderr, "slow: %i, fast: %i\n",
-// y, (uint) x);
+ x = (x << i) >> (2*D - d);
return x;
}
#endif
-#if 0
-uint __getbits(uint *B, int i, int d) {
- uint j,x;
-
- x = 0;
- for (j=0; j<d; j++) {
- x <<= 1;
- x += __getbit(B,i+j);
- }
- return x;
-}
-#endif
-
-
-
-#ifdef HAS_NATIVE_POPCOUNT
+#if HAS_NATIVE_POPCOUNT
static inline unsigned int popcount(unsigned int n){
asm ("popcnt %1, %0" : "=r" (n) : "0" (n));
return n;
}
-static inline unsigned int popcount8(unsigned int n) {
- return popcount(n & 0xff);
-}
+// static inline unsigned int popcount8(unsigned int n) {
+// return __builtin_popcount(n & 0xff);
+// }
-static inline unsigned int _fast_popcount(int x)
+static inline unsigned int _fast_popcount(uchar x)
{
- return popcount8(x);
+ return __builtin_popcount(x);
}
#else
-
static const unsigned int _popCount[] = {
0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,
1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
static inline unsigned int
_fast_popcount(int x) {
- return _popCount[x];
+ return _popCount[x & 0xff];
}
#endif
-static unsigned int __selecttbl[8*256];
+//static unsigned int __selecttbl[8*256];
static int built = 0;
void make___selecttbl(void) {
for (x = 0; x < 256; x++) {
__setbits(buf,0,8,x);
- for (r=0; r<8; r++) __selecttbl[(r<<8)+x] = -1;
+// for (r=0; r<8; r++) __selecttbl[(r<<8)+x] = -1;
r = 0;
for (i=0; i<8; i++) {
if (__getbit(buf,i)) {
- __selecttbl[(r<<8)+x] = i;
+ // __selecttbl[(r<<8)+x] = i;
r++;
}
}
}
}
-
-unsigned int __popCount(uint x) {
- uint r;
- #if 0
- r = x;
- r = r - ((r>>1) & 0x77777777) - ((r>>2) & 0x33333333) - ((r>>3) & 0x11111111);
- r = ((r + (r>>4)) & 0x0f0f0f0f) % 0xff;
- #elif 1
- r = x;
- r = ((r & 0xaaaaaaaa)>>1) + (r & 0x55555555);
- r = ((r & 0xcccccccc)>>2) + (r & 0x33333333);
- //r = ((r & 0xf0f0f0f0)>>4) + (r & 0x0f0f0f0f);
- r = ((r>>4) + r) & 0x0f0f0f0f;
- //r = ((r & 0xff00ff00)>>8) + (r & 0x00ff00ff);
- r = (r>>8) + r;
- //r = ((r & 0xffff0000)>>16) + (r & 0x0000ffff);
- r = ((r>>16) + r) & 63;
- #else
- r = _popCount[x & 0xff];
- x >>= 8;
- r += _popCount[x & 0xff];
- x >>= 8;
- r += _popCount[x & 0xff];
- x >>= 8;
- r += _popCount[x & 0xff];
- #endif
- return r;
-}
-
-
-unsigned int __popCount8(uint x) {
- uint r;
- #if 1
- r = x;
- r = ((r & 0xaa)>>1) + (r & 0x55);
- r = ((r & 0xcc)>>2) + (r & 0x33);
- r = ((r>>4) + r) & 0x0f;
- #else
- r = _popCount[x & 0xff];
- #endif
- return r;
-}
-
-
int selectd2_save(selectd2 * s, FILE * fp) {
uint wr = 0;
wr += fwrite(&s->n,sizeof(uint),1,fp);
int r;
uint *s;
- make___selecttbl();
+ //make___selecttbl();
if (L/LLL == 0) {
printf("ERROR: L=%d LLL=%d\n",L,LLL);
q++;
}
p = (q - select->buf) << 3;
- p += __selecttbl[((i-r-1)<<8)+(*q)];
+ p += selecttbl[((i-r-1)<<8)+(*q)];
}
return p;
}
int il;
int rr;
uchar *q;
+
if (i <= 0) return -1;
i--;
il = select->p[i>>logL];
if (il < 0) {
il = -il-1;
- //p = select->sl[(il<<logL)+(i & (L-1))];
- p = select->sl[il+(i & (L-1))];
- }
- else {
+ return select->sl[il+(i & (L-1))];
+
+ } else {
p = select->lp[i>>logL];
- //p += select->ss[(il<<(logL-logLLL))+(i & (L-1))/LLL];
+
p += select->ss[il+((i & (L-1))>>logLLL)];
r = i - (i & (LLL-1));
q = &(select->buf[p>>3]);
- rr = p & (8-1);
+ rr = p & 7;
- r -= _fast_popcount((*q ^ 0xff) >> (8-1-rr));
+ uint masked_q = *q ^ 0xff;
- while (1) {
- //rr = _popCount[*q ^ 0xff];
- rr = _fast_popcount(*q ^ 0xff);
- if (r + rr >= i) break;
+ r -= _fast_popcount(masked_q >> (7-rr));
+
+ for(;;) {
+ rr = _fast_popcount(masked_q);
+ if (rr >= i-r) {
+ p = (q - select->buf) << 3;
+ p += selecttbl[((i-r-1)<<8)+masked_q];
+ return p;
+ };
r += rr;
- //p += 8;
q++;
- }
- p = (q - select->buf) << 3;
- p += __selecttbl[((i-r-1)<<8)+(*q ^ 0xff)];
+ masked_q = *q ^ 0xff;
+ };
}
- return p;
}
int selectd2_select(selectd2 *select, int i,int f) {
q++;
}
p = (q - select->buf) << 3;
- p += __selecttbl[((i-r-1)<<8)+(*q)];
+ p += selecttbl[((i-r-1)<<8)+(*q)];
if ((i>>logL) == ((i+1)>>logL)) {
i++;
q++;
}
p2 = (q - select->buf) << 3;
- p2 += __selecttbl[((i-r-1)<<8)+(*q)];
+ p2 += selecttbl[((i-r-1)<<8)+(*q)];
}
else {
p2 = selectd2_select(select,i+2,f);
q++;
}
p = (q - select->buf) << 3;
- p += __selecttbl[((i-r-1)<<8)+(*q ^ 0xff)];
+ p += selecttbl[((i-r-1)<<8)+(*q ^ 0xff)];
if ((i>>logL) == ((i+1)>>logL)) {
i++;
q++;
}
p2 = (q - select->buf) << 3;
- p2 += __selecttbl[((i-r-1)<<8)+(*q ^ 0xff)];
+ p2 += selecttbl[((i-r-1)<<8)+(*q ^ 0xff)];
}
else {
p2 = selectd2_select(select,i+2,f);
}
int selects3_selectnext(selects3 *select, int i) {
- //return selects3_select(select,selects3_rank(select,i)+1);
+ //return selects3_select(select,selects3_rank(select,i)+1);
int d,x,w,y;
int r,j;
int z,ii;
w = __getbits(q,xoffset,d);
if (w >= j) {
- bool t1 = (w == j);
- bool t2 = (__getbit2(select->hi,((y << 3)+r)));
- if (t2) k2 += (t1);
- x += t1;
- r += t1;
+ if (w == j) {
+ if (__getbit2(select->hi,((y << 3)+r))) k2 ++;
+ x++;
+ r++;
+ xoffset += d;
+ };
break;
};
if(x==select->m) return (uint)-1;
- int c=(y << 3)+r;
- unsigned int mask = 0x00ffffff;
- unsigned int tmp = (select->hi[y] << (24+r)) | mask;
- unsigned int c_incr = __builtin_clz(tmp);
+ int c = (y << 3)+r;
+
+ uint mask = ~(0xffu << (8*sizeof(uint) - 8));
+ uint tmp = (select->hi[y] << ((8*sizeof(uint) - 8)+r)) | mask;
+ uint c_incr = __builtin_clz(tmp);
c += (c_incr & 7);
if (c_incr == 8) {
c += (8-r);
- int pp = c >> 3;
- while(select->hi[pp]==0) {
+
+ uchar * pp = &(select->hi[c >> 3]);
+
+ while(*pp == 0) {
pp++;
c += 8;
};
- while(!__getbit2(select->hi,c)) c++;
+
+ c += __builtin_clz(*pp) - 24;
};
- c -= (k2);
+ c -= k2;
- return __getbits(q,x*d,d)+((c)<<d);
+ return __getbits(q,xoffset,d)+((c)<<d);
}
int selects3_rank(selects3 *select, int i) {
d = select->d;
q = select->low;
- ii = i>>d;
+ ii = i >> d;
y = selectd2_select0(select->sd0, ii)+1;
- // selectd2_select2(select->sd0,ii,0,&y1,&y2);
- //y1++; y2++;
- //printf("y %d y1 %d %d\n",y,y1,y2-y1);
x = y - ii;
- j = i - (ii<<d);
+ j = i - (ii << d);
r = y & 7;
y >>= 3;
z = select->hi[y];
xoffset = x * d;
+
while (1) {
- if (((z << r) & 0x80) == 0) break;
+ if (((z << r) & 0x80) == 0) return x;
+
w = __getbits(q, xoffset, d);
- if (w >= j) {
- x += (w == j);
- break;
- }
+
+ if (w >= j) return x + (w == j);
+
x++;
r++;
xoffset += d;
z = select->hi[y];
}
}
-
- return x;
}