/////////////////////////////////////////// // i64 csa_search_lf(uchar *key,i64 keylen,CSA *csa,rank_t *ll,rank_t *rr) // returns the length of the longest suffix of key using BW // [*ll, *rr] is the range of key /////////////////////////////////////////// i64 csa_search_lf(uchar *key, i64 keylen, CSA *csa, rank_t *ll, rank_t *rr) { int c; i64 l,r,len2,pl,pr; if (keylen == 0) { *ll = 0; *rr = csa->n; return 0; } len2 = keylen; // c = csa->CtoA[key[keylen-1]]; c = csa->CtoA[getuint(key, keylen-1, csa->k2)]; l = csa->K[c+1]; r = csa->K[c+2]-1; // printf("search\n"); // printf("[%ld,%ld]\n",l,r); while (--keylen > 0) { pl = l; pr = r; // c = csa->CtoA[key[keylen-1]]; c = csa->CtoA[getuint(key, keylen-1, csa->k2)]; l = csa->K[c+1]-1 + csa->rankc(csa, l-1,c) + 1; r = csa->K[c+1]-1 + csa->rankc(csa, r,c); // printf("[%ld,%ld]\n",l,r); if (l > r) goto end; } end: if (keylen > 0) {l = pl; r = pr;} *ll = l; *rr = r; return len2-keylen; }
/* ARGSUSED */ int Xedit(cmd_t *cmd, disk_t *disk, mbr_t *mbr, mbr_t *tt, int offset) { const char *errstr; int pn, num, ret; prt_t *pp; pn = (int)strtonum(cmd->args, 0, 3, &errstr); if (errstr) { printf("partition number is %s: %s\n", errstr, cmd->args); return (CMD_CONT); } pp = &mbr->part[pn]; /* Edit partition type */ ret = Xsetpid(cmd, disk, mbr, tt, offset); #define EDIT(p, v, n, m) \ if ((num = ask_num(p, v, n, m)) != v) \ ret = CMD_DIRTY; \ v = num; /* Unused, so just zero out */ if (pp->id == DOSPTYP_UNUSED) { memset(pp, 0, sizeof(*pp)); printf("Partition %d is disabled.\n", pn); return (ret); } /* Change table entry */ if (ask_yn("Do you wish to edit in CHS mode?")) { int maxcyl, maxhead, maxsect; /* Shorter */ maxcyl = disk->real->cylinders - 1; maxhead = disk->real->heads - 1; maxsect = disk->real->sectors; /* Get data */ EDIT("BIOS Starting cylinder", pp->scyl, 0, maxcyl); EDIT("BIOS Starting head", pp->shead, 0, maxhead); EDIT("BIOS Starting sector", pp->ssect, 1, maxsect); EDIT("BIOS Ending cylinder", pp->ecyl, 0, maxcyl); EDIT("BIOS Ending head", pp->ehead, 0, maxhead); EDIT("BIOS Ending sector", pp->esect, 1, maxsect); /* Fix up off/size values */ PRT_fix_BN(disk, pp, pn); /* Fix up CHS values for LBA */ PRT_fix_CHS(disk, pp); } else { pp->bs = getuint(disk, "Partition offset", pp->bs, disk->real->size); pp->ns = getuint(disk, "Partition size", pp->ns, disk->real->size - pp->bs); /* Fix up CHS values */ PRT_fix_CHS(disk, pp); } #undef EDIT return (ret); }
static i64 psi12_psi(CSA *csa, i64 i) { i64 j,k; i64 x; i64 k2,p,n; i64 L; i64 b,d,sp; unsigned short *B; psi1 *ps; int runlen; ps = (psi1 *)csa->psi_struc; 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); } b = 0; j = i % L; n = ps->n; B = ps->B; b = 0; d = getbit(B+sp,b+1); if (d == 1) runlen = 1; else runlen = 0; b++; k = 1; while (k<=j) { if (runlen == 1) { b += DECODENUM(B+sp,b,&d); // printf("1. k = %d j = %d x = %ld d = %d runlen = %d\n",k,j,x,d,runlen); if (k+d-1 > j) { x += j-k+1; x %= (n+1); break; } x += d-1; k += d-1; // printf("11. k = %d j = %d x = %ld d = %d runlen = %d\n",k,j,x,d,runlen); } if (k > j) break; b += DECODENUM(B+sp,b,&d); // printf("2. k = %d j = %d x = %ld d = %d runlen = %d\n",k,j,x,d,runlen); x += d+1; x %= (n+1); k++; // printf("22. k = %d j = %d x = %ld d = %d runlen = %d\n",k,j,x,d,runlen); runlen = 1; } return x; }
static void test_getintegers(CuTest *tc) { init_tokens_str("ii 666 666 -42 -42"); CuAssertIntEquals(tc, 666, getid()); CuAssertIntEquals(tc, 666, getint()); CuAssertIntEquals(tc, 666, getuint()); CuAssertIntEquals(tc, -42, getint()); CuAssertIntEquals(tc, 0, getuint()); CuAssertIntEquals(tc, 0, getint()); }
static void psi1_iterator_readpage(psi1_iterator *pi, i64 page) { i64 L,i,j,k,id; i64 x,sp,n,b,d; unsigned short *B; i64 maxrun; psi1 *ps; n = pi->n; ps = pi->ps; L = ps->L; id = ps->id; maxrun = L; B = ps->B; j = L; if (page*L + j > n) j = n - page*L; x = getuint(ps->R,page*2,ps->k); sp = getuint(ps->R,page*2+1,ps->k); pi->buf[0] = x; b = 0; for (k=1; k<j; k++) { b += DECODENUM(B+sp,b,&d); if (id == ID_DIFF_GAMMA) { x += d; x %= n; pi->buf[k] = x; } else if (id == ID_DIFF_GAMMA_RL) { if (d <= maxrun*2) { if (d % 2 == 0) { for (i=0; i<d/2; i++) { x += 1; x %= n; if (k+i >= L) { printf("readpage: error k=%ld i=%ld l=%ld\n",k,i,L); } pi->buf[k+i] = x; } k += (d/2)-1; } else { x += (d+3)/2; x %= n; pi->buf[k] = x; } } else { x += d-maxrun+1; x %= n; pi->buf[k] = x; } } else { printf("??? id = %ld\n",id); } } pi->page = page; }
i64 read_idx(CSA *csa, char *fidx) { i64 isize; i64 i,id; uchar *p,*q; MMAP *mapidx; // printf("read_idx: %s\n",fidx); mapidx = mymmap(fidx); csa->mapidx = (void *)mapidx; p = q = mapidx->addr; if (p == NULL) { printf("read_idx: cannot mmap %s\n", fidx); exit(1); } isize = mapidx->len; i = getuint(p,0,4); p += 4; /* version */ if (i != VERSION) { printf("read_csa: Version %ld is not supported.\n",i); exit(1); } while (1) { if (p - q >= isize) break; id = getuint(p,0,1); p += 1; //printf("header ID=%ld\n",id); switch (id) { case ID_HEADER: read_header(csa, &p); break; case ID_SA: read_sa(csa, &p); break; case ID_ISA: read_isa(csa, &p); break; default: printf("read_csa: ID %ld is not supported.\n",id); break; } } return isize; }
static void read_header(CSA *csa, uchar **map) { i64 i,k,m,c; uchar *p; // printf("read_header\n"); p = *map; k = csa->k = getuint(p,0,1); p += 1; // printf("k = %ld\n",k); csa->n = getuint(p,0,k); p += k; /* length of the text */ csa->D = getuint(p,0,k); p += k; /* interval between two SA values stored explicitly */ csa->D2 = getuint(p,0,k); p += k; /* interval between two inverse SA values stored explicitly */ m = getuint(p,0,k); p += k; if (m != SIGMA) { /* alphabet size */ printf("error sigma=%ld\n",m); } csa->m = m = getuint(p,0,k); p += k; /* the number of distinct characters in the text */ for (i = 0; i < SIGMA; i++) csa->C[i] = 0; for (i = 0; i < m; i++) { c = getuint(p,0,1); p += 1; csa->C[c] = getuint(p,0,k); p += k; } *map = p; }
void solve(){ for (int i=1;i<=n;i++) now[i]=a[i], id[i]=0; for (int kase=m;kase--;){ int l=getuint(), r=getuint(), x=getuint(); for (int i=l;i<=r;i++) if (now[i]<=x){ id[i]^=1; if (id[i]) now[i]=b[i]; else now[i]=a[i]; } } long long ans=0; for (int i=1;i<=n;i++) ans+=now[i]; //for (int i=1;i<=n;i++) printf("%d\n", now[i]); printf("%lld\n", ans); }
static unsigned char * getchksum(unsigned char *p, unsigned char *endp, unsigned int *typep, unsigned int *lenp, Id *idp) { if ((p = getuint(p, endp, typep)) == 0) return 0; switch (*typep) { case 0: *lenp = 20; *idp = REPOKEY_TYPE_SHA1; return p; case 1: *lenp = 32; *idp = REPOKEY_TYPE_SHA256; return p; case 2: *lenp = 64; *idp = REPOKEY_TYPE_SHA512; return p; case 3: *lenp = 16; *idp = REPOKEY_TYPE_SHA512; return p; default: break; } return 0; }
static void dissector_init_oui(void) { FILE *fp; char buff[512], *ptr; struct vendor_id *ven; void **pos; fp = fopen("/etc/netsniff-ng/oui.conf", "r"); if (!fp) panic("No /etc/netsniff-ng/oui.conf found!\n"); memset(buff, 0, sizeof(buff)); while (fgets(buff, sizeof(buff), fp) != NULL) { buff[sizeof(buff) - 1] = 0; ven = xmalloc(sizeof(*ven)); ptr = buff; ptr = skips(ptr); ptr = getuint(ptr, &ven->id); ptr = skips(ptr); ptr = skipchar(ptr, ','); ptr = skips(ptr); ptr = strtrim_right(ptr, '\n'); ptr = strtrim_right(ptr, ' '); ven->vendor = xstrdup(ptr); ven->next = NULL; pos = insert_hash(ven->id, ven, ð_oui); if (pos) { ven->next = *pos; *pos = ven; } memset(buff, 0, sizeof(buff)); } fclose(fp); }
static void dissector_init_ports_tcp(void) { FILE *fp; char buff[512], *ptr; struct port_tcp *ptcp; void **pos; fp = fopen("/etc/netsniff-ng/tcp.conf", "r"); if (!fp) panic("No /etc/netsniff-ng/tcp.conf found!\n"); memset(buff, 0, sizeof(buff)); while (fgets(buff, sizeof(buff), fp) != NULL) { buff[sizeof(buff) - 1] = 0; ptcp = xmalloc(sizeof(*ptcp)); ptr = buff; ptr = skips(ptr); ptr = getuint(ptr, &ptcp->id); ptr = skips(ptr); ptr = skipchar(ptr, ','); ptr = skips(ptr); ptr = strtrim_right(ptr, '\n'); ptr = strtrim_right(ptr, ' '); ptcp->port = xstrdup(ptr); ptcp->next = NULL; pos = insert_hash(ptcp->id, ptcp, ð_ports_tcp); if (pos) { ptcp->next = *pos; *pos = ptcp; } memset(buff, 0, sizeof(buff)); } fclose(fp); }
static void dissector_init_ether_types(void) { FILE *fp; char buff[512], *ptr; struct ether_type *et; void **pos; fp = fopen("/etc/netsniff-ng/ether.conf", "r"); if (!fp) panic("No /etc/netsniff-ng/ether.conf found!\n"); memset(buff, 0, sizeof(buff)); while (fgets(buff, sizeof(buff), fp) != NULL) { buff[sizeof(buff) - 1] = 0; et = xmalloc(sizeof(*et)); ptr = buff; ptr = skips(ptr); ptr = getuint(ptr, &et->id); ptr = skips(ptr); ptr = skipchar(ptr, ','); ptr = skips(ptr); ptr = strtrim_right(ptr, '\n'); ptr = strtrim_right(ptr, ' '); et->type = xstrdup(ptr); et->next = NULL; pos = insert_hash(et->id, et, ð_ether_types); if (pos) { et->next = *pos; *pos = et; } memset(buff, 0, sizeof(buff)); } fclose(fp); }
/////////////////////////////////////////// // rank_t csa_inverse_lf(CSA *csa, pos_t suf) // returns SA^{-1}[i] using BW /////////////////////////////////////////// rank_t csa_inverse_lf(CSA *csa, pos_t suf) { i64 p,pos; i64 t; t = csa->D2 - 1; if (suf+t < csa->n) { // p = (suf+t) & (~t); p = ((suf+t) / (t+1)) * (t+1); pos = getuint(csa->ISA,p / (t+1),csa->k); while (p > suf) { pos = csa->LF(csa,pos); p--; } } else { p = csa->n; pos = 0; while (p > suf) { pos = csa->LF(csa,pos); p--; } } return pos; }
static void read_isa(CSA *csa, uchar **map) { i64 k,n; uchar *p; p = *map; n = csa->n; k = getuint(p,0,1); p += 1; csa->D2 = getuint(p,0,k); p += k; printf("read_isa n=%ld k=%ld D2=%d\n",n,k,csa->D2); csa->ISA = p; p += ((n-1) / csa->D2+1)*k; *map = p; }
static void read_sa(CSA *csa, uchar **map) { i64 k,n; uchar *p; p = *map; n = csa->n; k = getuint(p,0,1); p += 1; csa->D = getuint(p,0,k); p += k; printf("read_sa n=%ld k=%ld D=%d\n",n,k,csa->D); csa->SA = p; p += (n / csa->D+1)*k; *map = p; }
/////////////////////////////////////////// // int csa_child_r(CSA *csa,i64 len,rank_t l,rank_t r,uchar *tail,rank_t *ll,rank_t *rr) // returns the number of characters following suffixes [l,r] // tail stores the list of following characters // ll and rr store ranges for the following characters // lengths of head, ll, and rr must be at least csa->m (#distinct characters) /////////////////////////////////////////// int csa_child_r(CSA *csa, i64 len, rank_t l, rank_t r, uchar *tail, rank_t *ll, rank_t *rr) { int i,c,num; int sigma; uchar *substr; rank_t *ltmp, *rtmp; uchar *tailtmp; int *hc; sigma = csa->sigma; substr = mymalloc((len+1)*csa->k2); csa->substring(substr, csa, l, len); tailtmp = mymalloc(sigma * sizeof(*tailtmp) * csa->k2); ltmp = mymalloc(sigma * sizeof(*ltmp)); rtmp = mymalloc(sigma * sizeof(*ltmp)); hc = mymalloc(sigma * sizeof(*hc)); num = csa_child_r_sub(csa, len, l, r, 0, substr, tailtmp, ltmp, rtmp); for (c=0; c<sigma; c++) hc[c] = -1; // for (i=0; i<num; i++) hc[tailtmp[i]] = i; for (i=0; i<num; i++) hc[getuint(tailtmp,i,csa->k2)] = i; i = 0; for (c=0; c<sigma; c++) { if (hc[c] >= 0) { // tail[i] = tailtmp[hc[c]]; putuint(tail,i, getuint(tailtmp,hc[c],csa->k2), csa->k2); ll[i] = ltmp[hc[c]]; rr[i] = rtmp[hc[c]]; i++; } } free(hc); free(rtmp); free(ltmp); free(tailtmp); myfree(substr,(len+1)*csa->k2); return num; }
static void read_header(CSA *csa, uchar **map) { i64 i,k,m,c; uchar *p; i64 k2; // printf("read_header\n"); p = *map; k = csa->k = getuint(p,0,1); p += 1; // printf("k = %ld\n",k); csa->n = getuint(p,0,k); p += k; /* length of the text */ csa->D = getuint(p,0,k); p += k; /* interval between two SA values stored explicitly */ csa->D2 = getuint(p,0,k); p += k; /* interval between two inverse SA values stored explicitly */ // m = getuint(p,0,k); p += k; // if (m != SIGMA) { /* alphabet size */ // printf("error sigma=%ld\n",m); // } // csa->sigma = getuint(p,0,k)+1; p += k; // alphabet size csa->sigma = getuint(p,0,k); p += k; // alphabet size csa->m = m = getuint(p,0,k); p += k; /* the number of distinct characters in the text */ k2 = blog(csa->sigma-1)+1; // アルファベットを表現するのに必要なビット数 k2 = (k2+8-1)/8; // アルファベットを表現するのに必要なバイト数 csa->k2 = k2; csa->C = mymalloc(sizeof(*csa->C)*csa->sigma); // csa->CtoA = mymalloc(sizeof(*csa->CtoA)*csa->sigma); // csa->AtoC = mymalloc(sizeof(*csa->AtoC)*m); // csa->K = mymalloc(sizeof(*csa->K)*(csa->sigma+2)); // // for (i = 0; i < SIGMA; i++) csa->C[i] = 0; for (i = 0; i < csa->sigma; i++) csa->C[i] = 0; for (i = 0; i < m; i++) { int j,x; // c = getuint(p,0,1); p += 1; c = getuint(p,0,k2); p += k2; if (c >= csa->sigma) { printf("read_header: c = %d sigma = %d\n", c, csa->sigma); exit(1); } csa->C[c] = getuint(p,0,k); p += k; #if 0 printf("C[%d] = %ld (", c, csa->C[c]); x = c; for (j=0; j<csa->k2; j++) { printf("%c", x & 0xff); x >>= 8; } printf(")\n"); #endif } *map = p; }
/////////////////////////////////////////// // pos_t csa_lookup_lf(CSA *csa, rank_t i) // returns SA[i] using BW /////////////////////////////////////////// pos_t csa_lookup_lf(CSA *csa, rank_t i) { i64 v, D; v = 0; D = csa->D; while (i % D !=0) { i = csa->LF(csa,i); v++; } i = i / D; return (getuint(csa->SA,i,csa->k) + v) % (csa->n+1); }
/////////////////////////////////////////// // pos_t csa_lookupf(CSA *csa, rank_t i) // returns SA[i] using Psi /////////////////////////////////////////// pos_t csa_lookup(CSA *csa, rank_t i) { i64 v,D; v = 0; D = csa->D; while (i % D !=0) { i = csa->psi(csa,i); v++; } i = i / D; return getuint(csa->SA,i,csa->k)-v; }
/////////////////////////////////////////// // rank_t csa_psi_by_rankc_naive(CSA *csa, rank_t i) // returns Psi[i] using BW /////////////////////////////////////////// rank_t csa_psi_by_rankc_naive(CSA *csa, rank_t i) /* 0 <= i <= n */ { int c; if (i==0) return getuint(csa->ISA,0,csa->k); // last c = csa_head_rank(csa,i); i -= csa->K[c+1]; i++; return csa->selectc(csa,i,c); }
i64 write_isa(CSA *csa, FILE *f2, int isize) { i64 i,n,D2,k; n = csa->n; D2 = csa->D2; k = csa->k; writeint(1,k,f2); /* #bytes of integer */ writeint(k,D2,f2); /* interval between two SA values stored explicitly */ isize += 1+k; for (i = 0; i <= (n-1)/D2; i++) { display_progressbar("writing isa ",i,(n-1)/D2); writeint(k,getuint(csa->ISA,i,k),f2); isize += k; } return isize; }
/////////////////////////////////////////// // i64 csa_search(uchar *key,i64 keylen,CSA *csa,rank_t *li,rank_t *ri) // returns the length of the longest suffix of key using psi // [*li, *ri] is the range of key /////////////////////////////////////////// i64 csa_search(uchar *key,i64 keylen,CSA *csa,rank_t *li,rank_t *ri) { i64 c,h; i64 l,r,l0,r0,pl,pr; i64 len; // pl= 1; pr = csa->n; pl= 0; pr = csa->n; if (keylen == 0) { *li = pl; *ri = pr; return 0; } // c = csa->CtoA[key[keylen-1]]; c = csa->CtoA[getuint(key, keylen-1, csa->k2)]; r = csa->K[c+2]-1; l = csa->K[c+1]; len = 0; if (l > r) goto end; len++; for (h = keylen-2; h >= 0; h--) { pl = l; pr = r; // c = csa->CtoA[key[h]]; c = csa->CtoA[getuint(key, h, csa->k2)]; r = csa->K[c+2]-1; l = csa->K[c+1]; if (l > r) goto end; l0 = l; r0 = r; r = csa->psi_pred(csa,pr,l0,r0); l = csa->psi_succ(csa,pl,l0,r0); if (l > r) goto end; len++; } end: if (len < keylen) {l = pl; r = pr;} *li = l; *ri = r; return len; }
i64 write_sa(CSA *csa, FILE *f2, int isize) { i64 i,n,D,k; n = csa->n; D = csa->D; k = csa->k; printf("write_sa n=%ld D=%ld k=%ld\n",n,D,k); writeint(1,k,f2); /* #bytes of integer */ writeint(k,D,f2); /* interval between two SA values stored explicitly */ isize += 1+k; for (i = 0; i <= n/D; i++) { display_progressbar("writing sa ",i,n/D); // printf("sa[%ld] = %ld\n",i,getuint(sa->SA,i,k)); writeint(k,getuint(csa->SA,i,k),f2); isize += k; } return isize; }
/////////////////////////////////////////// // rank_t csa_inverse(CSA *csa, pos_t suf) // returns SA^{-1}[i] using Psi /////////////////////////////////////////// rank_t csa_inverse(CSA *csa, pos_t suf) { pos_t p; rank_t r; i64 D2; D2 = csa->D2; p = (suf/D2)*D2+1; r = getuint(csa->ISA,suf/D2,csa->k); while (p < suf+1) { r = csa->psi(csa,r); p++; } return r; }
/////////////////////////////////////////// // rank_t csa_inverse_lf(CSA *csa, pos_t suf) // returns SA^{-1}[i] using BW /////////////////////////////////////////// rank_t csa_inverse_lf(CSA *csa, pos_t suf) { i64 p,rank; i64 t; t = csa->D2; if (suf+t-1 < csa->n) { p = ((suf+t-1) / t) * t; // D2の倍数に切り上げ rank = getuint(csa->ISA,p / t,csa->k); while (p > suf) { rank = csa->LF(csa,rank); p--; } } else { p = csa->n; rank = 0; while (p > suf) { rank = csa->LF(csa,rank); p--; } } return rank; }
struct solv_zchunk * solv_zchunk_open(FILE *fp, unsigned int streamid) { struct solv_zchunk *zck; unsigned char *p; unsigned int hdr_size; /* preface + index + signatures */ unsigned int lead_size; unsigned int preface_size; unsigned int index_size; zck = solv_calloc(1, sizeof(*zck)); /* read and parse the lead, read the complete header */ zck->hdr = solv_calloc(15, 1); zck->hdr_end = zck->hdr + 15; if (fread(zck->hdr, 15, 1, fp) != 1 || memcmp(zck->hdr, "\000ZCK1", 5) != 0) return open_error(zck); p = zck->hdr + 5; if ((p = getchksum(p, zck->hdr_end, &zck->hdr_chk_type, &zck->hdr_chk_len, &zck->hdr_chk_id)) == 0) return open_error(zck); if ((p = getuint(p, zck->hdr_end, &hdr_size)) == 0 || hdr_size > MAX_HDR_SIZE) return open_error(zck); lead_size = p - zck->hdr + zck->hdr_chk_len; zck->hdr = solv_realloc(zck->hdr, lead_size + hdr_size); zck->hdr_end = zck->hdr + lead_size + hdr_size; if (fread(zck->hdr + 15, lead_size + hdr_size - 15, 1, fp) != 1) return open_error(zck); /* verify header checksum to guard against corrupt files */ if (zck->hdr_chk_id) { Chksum *chk = solv_chksum_create(zck->hdr_chk_id); if (!chk) return open_error(zck); solv_chksum_add(chk, zck->hdr, lead_size - zck->hdr_chk_len); solv_chksum_add(chk, zck->hdr + lead_size, hdr_size); if (memcmp(solv_chksum_get(chk, 0), zck->hdr + (lead_size - zck->hdr_chk_len), zck->hdr_chk_len) != 0) { solv_chksum_free(chk, 0); return open_error(zck); } solv_chksum_free(chk, 0); } /* parse preface: data chksum, flags, compression */ p = zck->hdr + lead_size; if (p + zck->hdr_chk_len > zck->hdr_end) return open_error(zck); zck->data_chk_ptr = p; p += zck->hdr_chk_len; #ifdef VERIFY_DATA_CHKSUM if (zck->hdr_chk_id && (zck->data_chk = solv_chksum_create(zck->hdr_chk_id)) == 0) return open_error(zck); #endif if ((p = getuint(p, zck->hdr_end, &zck->flags)) == 0) return open_error(zck); if ((zck->flags & ~(3)) != 0) return open_error(zck); if ((p = getuint(p, zck->hdr_end, &zck->comp)) == 0 || (zck->comp != 0 && zck->comp != 2)) return open_error(zck); /* only uncompressed + zstd supported */ /* skip all optional elements if present */ if ((zck->flags & 2) != 0) { unsigned int nopt, lopt; if ((p = getuint(p, zck->hdr_end, &nopt)) == 0) return open_error(zck); for (; nopt != 0; nopt--) { if ((p = getuint(p, zck->hdr_end, &lopt)) == 0) return open_error(zck); if ((p = getuint(p, zck->hdr_end, &lopt)) == 0) return open_error(zck); if (p + lopt > zck->hdr_end) return open_error(zck); p += lopt; } } preface_size = p - (zck->hdr + lead_size); /* parse index: index size, index chksum type, num chunks, chunk data */ if ((p = getuint(p, zck->hdr_end, &index_size)) == 0) return open_error(zck); if (hdr_size < preface_size + index_size) return open_error(zck); if ((p = getchksum(p, zck->hdr_end, &zck->chunk_chk_type, &zck->chunk_chk_len, &zck->chunk_chk_id)) == 0) return open_error(zck); if ((p = getuint(p, zck->hdr_end, &zck->nchunks)) == 0 || zck->nchunks > MAX_CHUNK_CNT) return open_error(zck); /* setup decompressor */ if (zck->comp == 2) { if ((zck->dctx = ZSTD_createDCtx()) == 0) return open_error(zck); } zck->fp = fp; zck->chunks = p; zck->streamid = streamid; if (streamid == 0) { zck->nchunks = zck->nchunks ? 1 : 0; /* limit to dict chunk */ return zck; } /* setup dictionary */ if (!nextchunk(zck, 0)) { zck->fp = 0; return open_error(zck); } if (zck->comp == 2 && zck->buf_avail) { if ((zck->ddict = ZSTD_createDDict(zck->buf, zck->buf_avail)) == 0) { zck->fp = 0; return open_error(zck); } } zck->buf = solv_free(zck->buf); zck->buf_used = 0; zck->buf_avail = 0; /* ready to read the rest of the chunks */ return zck; }
i64 psi1_read(CSA *csa, char *fname) { FILE *f1; i64 psize1,psize2; i64 n; int k,l,id,id2; char *fpsi, *fpsd, *fname2; psi1 *ps; uchar *p,*q; csa->psi_struc = ps = mymalloc(sizeof(psi1)); k = strlen(fname); fname2 = mymalloc(k-4+1); strncpy(fname2,fname,k-4); fname2[k-4] = 0; k -= 5; initranktables(); mkdecodetable(); fpsi = mymalloc(k+5+1); // fpsd = mymalloc(k+5); // sprintf(fpsd,"%s.psd",fname2); fpsd = fname; // printf("psi_read: read %s\n",fpsd); ps->mappsd = mymmap(fpsd); if (ps->mappsd->addr==NULL) { perror("psi1_read: mmap2\n"); exit(1); } p = q = (uchar *)ps->mappsd->addr; psize1 = ps->mappsd->len; id = getuint(p,0,1); p += 1; if (id != ID_PSI) { printf("read_psi: id = %d is not supported.\n",id); exit(1); } ps->k = k = getuint(p,0,1); p += 1; ps->n = n = getuint(p,0,k); p += k; ps->L = l = getuint(p,0,k); p += k; id = getuint(p,0,1); p += 1; // printf("read_psi: psi_id = %d L = %d\n",id,l); csa->id = ps->id = id; id2 = id & 0x3f; switch (id2) { case ID_DIFF_GAMMA: printf("#psi format = GAMMA L=%d C=%d\n",l,(id>>7)); sprintf(fpsi,"%s.psi",fname2); break; case ID_DIFF_GAMMA_RL: printf("#psi format = GAMMA_RL L=%d C=%d\n",l,(id>>7)); sprintf(fpsi,"%s.pri",fname2); break; case ID_DIFF_GAMMA_SPARSE: printf("#psi format = GAMMA_SPARSE L=%d C=%d\n",l,(id>>7)); sprintf(fpsi,"%s.psi",fname2); break; case ID_DIFF_GAMMA_RL_SPARSE: printf("#psi format = GAMMA_RL_SPARSE L=%d C=%d\n",l,(id>>7)); sprintf(fpsi,"%s.pri",fname2); break; case ID_DIFF_GAMMA_RR: printf("#psi format = GAMMA_RR L=%d C=%d\n",l,(id>>7)); sprintf(fpsi,"%s.pxi",fname2); break; default: printf("read_csa: ID %d is not supported.\n",id); break; } if (id & ID_COMPPTR) { printf("COMPPTR\n"); ps->sx = mymalloc(sizeof(SPARSEARRAY)); ps->sb = mymalloc(sizeof(SPARSEARRAY)); SPARSEARRAY_read(ps->sx, &p); SPARSEARRAY_read(ps->sb, &p); } else { ps->R = p; } // printf("psize = %ld\n",psize); //// read psi // printf("psi_read: map %s\n",fpsi); ps->mappsi = mymmap(fpsi); if (ps->mappsi->addr==NULL) { perror("psi1_read: mmap1\n"); exit(1); } ps->B = (unsigned short *)ps->mappsi->addr; psize2 = ps->mappsi->len; // printf("psize2 = %ld\n",psize2); // printf("psi1_read: psize1 = %ld psize2 = %ld\n",psize1,psize2); ps->psize = psize1 + psize2; free(fpsi); // free(fpsd); free(fname2); // user-specific functions csa->psi = psi1_psi; if (id2 == ID_DIFF_GAMMA_RR) { csa->psi = psi12_psi; csa->psi_pred = csa_psi_pred_naive; csa->psi_succ = csa_psi_succ_naive; } else { if ((id & ID_COMPPTR) || 0) { csa->psi_pred = csa_psi_pred_naive; csa->psi_succ = csa_psi_succ_naive; } else { csa->psi_succ = psi1_succ_tmp; csa->psi_pred = psi1_pred_tmp; // csa->psi_succ = csa_psi_succ_naive; // csa->psi_pred = csa_psi_pred_naive; } } // default functions csa->LF = csa_LF_by_psi; csa->lookup = csa_lookup; csa->inverse = csa_inverse; csa->text = csa_text; csa->substring = csa_substring; csa->T = csa_T; csa->head = csa_head_rank; csa->search = csa_search; csa->searchsub = csa_searchsub; return psize1 + psize2; }
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; }
static i64 psi1_pred(CSA *csa, i64 pl, i64 l, i64 r) { i64 m,ll,rr,j; i64 x; i64 sp,L,d,n; uchar *R; unsigned short *B, *buf, offset; i64 maxrun; int k; psi1 *ps; ps = (psi1 *)csa->psi_struc; R = ps->R; B = ps->B; L = ps->L; k = ps->k; n = ps->n; maxrun = L; ll = (l+L-1) / L; // ll = l / L + 1; rr = r / L; while (ll <= rr) { m = (ll + rr) / 2; x = getuint(R,m*2,k); if (x >= pl) rr = m-1; else ll = m+1; } m = rr*L; x = getuint(R,(m / L)*2,k); sp = getuint(R,(m / L)*2+1,k); // r = (rr+1)*L; if (r > n) r = n+1; if ((rr+1)*L <= r) r = (rr+1)*L; else r = r+1; if (r > n) r = n+1; buf = B + sp; offset = 0; switch (ps->id & 0x3f) { case ID_DIFF_GAMMA: while (m < r) { if (m >= l && x >= pl) break; offset += DECODENUM(buf,offset,&d); x += d; x %= (n+1); m++; } return m; break; case ID_DIFF_GAMMA_RL: while (m < r) { if (m >= l && x >= pl) break; offset += DECODENUM(buf,offset,&d); if (d <= maxrun*2) { if (d % 2 == 0) { for (j=0; j<d/2 && m<r; j++) { if (m >= l && x >= pl) goto end; x += 1; x %= (n+1); m++; } } else { x += (d+3)/2; x %= (n+1); m++; } } else { x += d-maxrun+1; x %= (n+1); m++; } } end: return m; break; } return -1; }
static int nextchunk(struct solv_zchunk *zck, unsigned int streamid) { unsigned char *p = zck->chunks; unsigned char *chunk_chk_ptr; unsigned int sid, chunk_len, uncompressed_len; unsigned char *cbuf; /* free old buffer */ zck->buf = solv_free(zck->buf); zck->buf_avail = 0; zck->buf_used = 0; for (;;) { if (zck->nchunks == 0) { zck->chunks = p; return 1; /* EOF reached */ } if (p >= zck->hdr_end) return 0; sid = streamid ? 1 : 0; /* check if this is the correct stream */ if ((zck->flags & 1) != 0 && (p = getuint(p, zck->hdr_end, &sid)) == 0) return 0; chunk_chk_ptr = p; /* remember for verification */ p += zck->chunk_chk_len; if (p >= zck->hdr_end) return 0; if ((p = getuint(p, zck->hdr_end, &chunk_len)) == 0) return 0; if ((p = getuint(p, zck->hdr_end, &uncompressed_len)) == 0) return 0; zck->nchunks--; if (sid == streamid) break; /* skip the chunk, but the dict chunk must come first */ if (streamid == 0 || skip_bytes(zck->fp, chunk_len, zck->data_chk) == 0) return 0; } zck->chunks = p; /* ok, read the compressed chunk */ if (!chunk_len) return uncompressed_len ? 0 : 1; cbuf = solv_malloc(chunk_len); if (fread(cbuf, chunk_len, 1, zck->fp) != 1) { solv_free(cbuf); return 0; } if (zck->data_chk) solv_chksum_add(zck->data_chk, cbuf, chunk_len); /* verify the chunk checksum */ if (zck->chunk_chk_id) { Chksum *chk = solv_chksum_create(zck->chunk_chk_id); if (!chk) { solv_free(cbuf); return 0; } solv_chksum_add(chk, cbuf, chunk_len); if (memcmp(solv_chksum_get(chk, 0), chunk_chk_ptr, zck->chunk_chk_len) != 0) { solv_chksum_free(chk, 0); solv_free(cbuf); return 0; } solv_chksum_free(chk, 0); } /* uncompress */ if (zck->comp == 0) { /* not compressed */ if (chunk_len != uncompressed_len) { solv_free(cbuf); return 0; } zck->buf = cbuf; zck->buf_avail = uncompressed_len; return 1; } if (zck->comp == 2) { /* zstd compressed */ size_t r; zck->buf = solv_malloc(uncompressed_len + 1); /* +1 so we can detect too large frames */ if (zck->ddict) r = ZSTD_decompress_usingDDict(zck->dctx, zck->buf, uncompressed_len + 1, cbuf, chunk_len, zck->ddict); else r = ZSTD_decompressDCtx(zck->dctx, zck->buf, uncompressed_len + 1, cbuf, chunk_len); solv_free(cbuf); if (r != uncompressed_len) return 0; zck->buf_avail = uncompressed_len; return 1; } solv_free(cbuf); return 0; }