int decodegamma(unsigned short *B,int p,int *ans) { int w,x; int w2; #if 0 x = getbitD(B,1+p); b = R6b[x]; if (b>0) { *ans = R6x[x]; return b; } #endif w = getzerorun(B,p); #if 0 x = 1; for (i=0;i<w;i++) { x <<= 1; x += getbit(B,1+p+w+1+i); } #else /* psigamma_ */ p += w+1; x = 1; w2 = w; while (w2 > DD) { x <<= DD; x += getbitD(B,1+p); p += DD; w2 -= DD; /* w return value */ } x <<= w2; x += (getbitD(B,1+p)>>(DD-w2)); #endif *ans = x; return 2*w+1; }
static int decodedelta(unsigned short *B,i64 p,i64 *ans) { i64 l,w,w2; i64 x; l = decodegamma(B,p,&w); #if 0 x = 1; for (i=1;i<w;i++) { x <<= 1; x += getbit(B,1+p+l+i-1); } #else p += l; x = 1; w2 = w-1; while (w2 > DD) { x <<= DD; x += getbitD(B,1+p); p += DD; w2 -= DD; } x <<= w2; x += (getbitD(B,1+p)>>(DD-w2)); #endif *ans = x; return l+w-1; }
static int decodegamma(unsigned short *B,i64 p,i64 *ans) { i64 w,w2; i64 x; w = getzerorun(B,p); #if 0 x = 1; for (i=0;i<w;i++) { x <<= 1; x += getbit(B,1+p+w+1+i); } #else p += w+1; x = 1; w2 = w; while (w2 > DD) { x <<= DD; x += getbitD(B,1+p); p += DD; w2 -= DD; } x <<= w2; x += (getbitD(B,1+p)>>(DD-w2)); #endif *ans = x; return 2*w+1; }
static int getzerorun(unsigned short *B,i64 p) { i64 w,w2; #if 0 w = 0; while (getbit(B,1+p+w)==0) w++; #else w = 0; while (1) { w2 = R4[getbitD(B,1+p)]; w += w2; if (w2 < DD) break; p += DD; } #endif return w; }
static i64 psi1_psi(CSA *csa, i64 i) { i64 j,k; i64 x; i64 k2,p,n; i64 L; i64 b,d,sp; i64 maxrun; unsigned short *B; psi1 *ps; ps = (psi1 *)csa->psi_struc; // printf("psi1_psi[%ld] (no run)\n",i); #ifdef DEBUG if (i > csa->n || i < 1) { printf("error csa2_psi i=%u n=%u\n",i,csa->n); exit(1); } #endif L = ps->L; if (ps->id & ID_COMPPTR) { x = SPARSEARRAY_select(ps->sx, (i/L)+1) % (csa->n+1); sp = SPARSEARRAY_select(ps->sb, (i/L)+1); } else { x = getuint(ps->R,(i / L)*2,ps->k); sp = getuint(ps->R,(i / L)*2+1,ps->k); } maxrun = L; b = 0; j = i % L; n = ps->n; B = ps->B; switch (ps->id & 0x3f) { case ID_DIFF_GAMMA: case ID_DIFF_GAMMA_SPARSE: k = 0; while (k < j) { p = getbitD(B+sp,1+b); k2 = R5n[p]; if (k2 == 0) { b += DECODENUM(B+sp,b,&d); x += d; x %= (n+1); k++; } else { if (k+k2 > j) break; k += k2; b += R5b[p]; x += R5x[p]; x %= (n+1); } } for (; k<j; k++) { b += DECODENUM(B+sp,b,&d); x += d; x %= (n+1); } break; case ID_DIFF_GAMMA_RL: case ID_DIFF_GAMMA_RL_SPARSE: // psi1_decbuf[0] = x; b = 0; for (k=1; k<=j; k++) { b += DECODENUM(B+sp,b,&d); if (d <= maxrun*2) { if (d % 2 == 0) { #if 0 for (i=0; i<d/2; i++) { x += 1; x %= (n+1); if (k+i >= L) { printf("psi1_psi: error k=%d i=%d l=%d\n",k,i,L); } // psi1_decbuf[k+i] = x; if (k+i == j) break; } #else if (k+d/2-1 >= j) { x += j-k+1; x %= (n+1); break; } x += d/2; #endif k += (d/2)-1; } else { x += (d+3)/2; x %= (n+1); // psi1_decbuf[k] = x; } } else { x += d-maxrun+1; x %= (n+1); // psi1_decbuf[k] = x; } } // x = psi1_decbuf[j]; break; } #ifdef DEBUG if (x < 0 || x > csa->n) { printf("error csa2_psi(%u) %u\n",i,x); } #endif // printf("psi1_psi: psi[%ld] = %ld\n",i,x); return x; }
inline int csa_psi(CSA *SA, int i) { int j,k,b,d,x; int k2,p,n; int l; unsigned short *B; #ifdef DEBUG if (i > SA->n || i < 1) { printf("error csa2_psi i=%d n=%d\n",i,SA->n); exit(1); } #endif l = SA->l; x = SA->R[(i / l)*2]; b = SA->R[(i / l)*2+1]; j = i % l; n = SA->n; B = SA->B; #if 0 for (k=0; k<j; k++) { b += DECODENUM(B,b,&d); x += d; if (x > n) { //printf("i %d k %d d %d x %d n %d\n",i,k,d,x,n); x = -1; k--; } //printf("k %d j %d b %d \n",k,j,b); } #else k = 0; while (k < j) { p = getbitD(B,1+b); k2 = R5n[p]; if (k2 == 0) { b += DECODENUM(B,b,&d); x += d; k++; if (x > n) { x = -1; k--; } } else { if (k+k2 > j) break; k += k2; b += R5b[p]; x += R5x[p]; } } for (; k<j; k++) { b += DECODENUM(B,b,&d); x += d; if (x > n) { x = -1; k--; } } #endif #ifdef DEBUG if (x < 0 || x > SA->n) { printf("error csa2_psi(%d) %d\n",i,x); } #endif return x; }