X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Frepo_write.c;h=11002b44d3d368fb83fe64716c5697441a9d75ba;hb=05baf54bdf745b05c54355438ab9155a8e64c346;hp=7675f44164145928d464a2125d313dda8d1d1bda;hpb=0a5baff771db11cea25e646677e72765e164e57a;p=platform%2Fupstream%2Flibsolv.git diff --git a/src/repo_write.c b/src/repo_write.c index 7675f44..11002b4 100644 --- a/src/repo_write.c +++ b/src/repo_write.c @@ -7,12 +7,12 @@ /* * repo_write.c - * + * * Write Repo data out to a file in solv format - * - * See doc/README.format for a description + * + * See doc/README.format for a description * of the binary file format - * + * */ #include @@ -22,6 +22,7 @@ #include #include #include +#include #include "pool.h" #include "util.h" @@ -43,9 +44,9 @@ typedef struct needid { * increment need Id * idarray: array of Ids, ID_NULL terminated * needid: array of Id->NeedId - * + * * return size of array (including trailing zero) - * + * */ static void @@ -92,7 +93,7 @@ incneedidarray(Pool *pool, Id *idarray, NeedId *needid) /* - * + * */ static int @@ -136,15 +137,17 @@ needid_cmp_need_s(const void *ap, const void *bp, void *dp) */ static void -write_u32(FILE *fp, unsigned int x) +write_u32(Repodata *data, unsigned int x) { + FILE *fp = data->fp; + if (data->error) + return; if (putc(x >> 24, fp) == EOF || putc(x >> 16, fp) == EOF || putc(x >> 8, fp) == EOF || putc(x, fp) == EOF) { - perror("write error u32"); - exit(1); + data->error = pool_error(data->repo->pool, -1, "write error u32: %s", strerror(errno)); } } @@ -154,12 +157,13 @@ write_u32(FILE *fp, unsigned int x) */ static void -write_u8(FILE *fp, unsigned int x) +write_u8(Repodata *data, unsigned int x) { - if (putc(x, fp) == EOF) + if (data->error) + return; + if (putc(x, data->fp) == EOF) { - perror("write error u8"); - exit(1); + data->error = pool_error(data->repo->pool, -1, "write error u8: %s", strerror(errno)); } } @@ -168,12 +172,13 @@ write_u8(FILE *fp, unsigned int x) */ static void -write_blob(FILE *fp, void *data, int len) +write_blob(Repodata *data, void *blob, int len) { - if (len && fwrite(data, len, 1, fp) != 1) + if (data->error) + return; + if (len && fwrite(blob, len, 1, data->fp) != 1) { - perror("write error blob"); - exit(1); + data->error = pool_error(data->repo->pool, -1, "write error blob: %s", strerror(errno)); } } @@ -182,8 +187,11 @@ write_blob(FILE *fp, void *data, int len) */ static void -write_id(FILE *fp, Id x) +write_id(Repodata *data, Id x) { + FILE *fp = data->fp; + if (data->error) + return; if (x >= (1 << 14)) { if (x >= (1 << 28)) @@ -196,28 +204,28 @@ write_id(FILE *fp, Id x) putc((x >> 7) | 128, fp); if (putc(x & 127, fp) == EOF) { - perror("write error id"); - exit(1); + data->error = pool_error(data->repo->pool, -1, "write error id: %s", strerror(errno)); } } static inline void -write_id_eof(FILE *fp, Id x, int eof) +write_id_eof(Repodata *data, Id x, int eof) { if (x >= 64) x = (x & 63) | ((x & ~63) << 1); - write_id(fp, x | (eof ? 0 : 64)); + write_id(data, x | (eof ? 0 : 64)); } static inline void -write_str(FILE *fp, const char *str) +write_str(Repodata *data, const char *str) { - if (fputs(str, fp) == EOF || putc(0, fp) == EOF) + if (data->error) + return; + if (fputs(str, data->fp) == EOF || putc(0, data->fp) == EOF) { - perror("write error str"); - exit(1); + data->error = pool_error(data->repo->pool, -1, "write error str: %s", strerror(errno)); } } @@ -226,14 +234,14 @@ write_str(FILE *fp, const char *str) */ static void -write_idarray(FILE *fp, Pool *pool, NeedId *needid, Id *ids) +write_idarray(Repodata *data, Pool *pool, NeedId *needid, Id *ids) { Id id; if (!ids) return; if (!*ids) { - write_u8(fp, 0); + write_u8(data, 0); return; } for (;;) @@ -245,10 +253,10 @@ write_idarray(FILE *fp, Pool *pool, NeedId *needid, Id *ids) id = (id & 63) | ((id & ~63) << 1); if (!*ids) { - write_id(fp, id); + write_id(data, id); return; } - write_id(fp, id | 64); + write_id(data, id | 64); } } @@ -262,7 +270,7 @@ cmp_ids(const void *pa, const void *pb, void *dp) #if 0 static void -write_idarray_sort(FILE *fp, Pool *pool, NeedId *needid, Id *ids, Id marker) +write_idarray_sort(Repodata *data, Pool *pool, NeedId *needid, Id *ids, Id marker) { int len, i; Id lids[64], *sids; @@ -271,7 +279,7 @@ write_idarray_sort(FILE *fp, Pool *pool, NeedId *needid, Id *ids, Id marker) return; if (!*ids) { - write_u8(fp, 0); + write_u8(data, 0); return; } for (len = 0; len < 64 && ids[len]; len++) @@ -336,7 +344,7 @@ write_idarray_sort(FILE *fp, Pool *pool, NeedId *needid, Id *ids, Id marker) we might want to skip writing them out. */ if (id >= 64) id = (id & 63) | ((id & ~63) << 1); - write_id(fp, id | 64); + write_id(data, id | 64); } id = sids[i]; if (id == marker) @@ -345,7 +353,7 @@ write_idarray_sort(FILE *fp, Pool *pool, NeedId *needid, Id *ids, Id marker) id = id - old + 1; if (id >= 64) id = (id & 63) | ((id & ~63) << 1); - write_id(fp, id); + write_id(data, id); if (sids != lids) solv_free(sids); } @@ -389,6 +397,7 @@ struct cbdata { Id lastlen; int doingsolvables; /* working on solvables data */ + int filelistmode; }; #define NEEDED_BLOCK 1023 @@ -397,9 +406,11 @@ struct cbdata { #define EXTDATA_BLOCK 4095 static inline void -data_addid(struct extdata *xd, Id x) +data_addid(struct extdata *xd, Id sx) { + unsigned int x = (unsigned int)sx; unsigned char *dp; + xd->buf = solv_extend(xd->buf, xd->len, 5, 1, EXTDATA_BLOCK); dp = xd->buf + xd->len; @@ -418,11 +429,57 @@ data_addid(struct extdata *xd, Id x) } static inline void -data_addideof(struct extdata *xd, Id x, int eof) +data_addideof(struct extdata *xd, Id sx, int eof) { - if (x >= 64) - x = (x & 63) | ((x & ~63) << 1); - data_addid(xd, (eof ? x: x | 64)); + unsigned int x = (unsigned int)sx; + unsigned char *dp; + + xd->buf = solv_extend(xd->buf, xd->len, 5, 1, EXTDATA_BLOCK); + dp = xd->buf + xd->len; + + if (x >= (1 << 13)) + { + if (x >= (1 << 27)) + *dp++ = (x >> 27) | 128; + if (x >= (1 << 20)) + *dp++ = (x >> 20) | 128; + *dp++ = (x >> 13) | 128; + } + if (x >= (1 << 6)) + *dp++ = (x >> 6) | 128; + *dp++ = eof ? (x & 63) : (x & 63) | 64; + xd->len = dp - xd->buf; +} + +static inline int +data_addideof_len(Id sx) +{ + unsigned int x = (unsigned int)sx; + if (x >= (1 << 13)) + { + if (x >= (1 << 27)) + return 5; + return x >= (1 << 20) ? 4 : 3; + } + return x >= (1 << 6) ? 2 : 1; +} + +static void +data_addid64(struct extdata *xd, unsigned int x, unsigned int hx) +{ + if (hx) + { + if (hx > 7) + { + data_addid(xd, (Id)(hx >> 3)); + xd->buf[xd->len - 1] |= 128; + hx &= 7; + } + data_addid(xd, (Id)(x | 0x80000000)); + xd->buf[xd->len - 5] = (x >> 28) | (hx << 4) | 128; + } + else + data_addid(xd, (Id)x); } static void @@ -499,18 +556,14 @@ data_addidarray_sort(struct extdata *xd, Pool *pool, NeedId *needid, Id *ids, Id } /* XXX If difference is zero we have multiple equal elements, we might want to skip writing them out. */ - if (id >= 64) - id = (id & 63) | ((id & ~63) << 1); - data_addid(xd, id | 64); + data_addideof(xd, id, 0); } id = sids[i]; if (id == marker) id = 0; else id = id - old + 1; - if (id >= 64) - id = (id & 63) | ((id & ~63) << 1); - data_addid(xd, id); + data_addideof(xd, id, 1); if (sids != lids) solv_free(sids); } @@ -642,8 +695,8 @@ repo_write_collect_needed(struct cbdata *cbdata, Repo *repo, Repodata *data, Rep { if (cbdata->oldschema) { - fprintf(stderr, "nested structs not yet implemented\n"); - exit(1); + cbdata->target->error = pool_error(cbdata->repo->pool, -1, "nested fixarray structs not yet implemented"); + return SEARCH_NEXT_KEY; } cbdata->oldschema = cbdata->schema; cbdata->oldsp = cbdata->sp; @@ -733,7 +786,7 @@ repo_write_adddata(struct cbdata *cbdata, Repodata *data, Repokey *key, KeyValue rm = cbdata->keymap[cbdata->keymapstart[data->repodataid] + (key - data->keys)]; if (!rm) return SEARCH_NEXT_KEY; /* we do not want this one */ - + if (cbdata->target->keys[rm].storage == KEY_STORAGE_VERTICAL_OFFSET) { xd = cbdata->extdata + rm; /* vertical buffer */ @@ -773,9 +826,18 @@ repo_write_adddata(struct cbdata *cbdata, Repodata *data, Repokey *key, KeyValue case REPOKEY_TYPE_SHA1: data_addblob(xd, (unsigned char *)kv->str, SIZEOF_SHA1); break; + case REPOKEY_TYPE_SHA224: + data_addblob(xd, (unsigned char *)kv->str, SIZEOF_SHA224); + break; case REPOKEY_TYPE_SHA256: data_addblob(xd, (unsigned char *)kv->str, SIZEOF_SHA256); break; + case REPOKEY_TYPE_SHA384: + data_addblob(xd, (unsigned char *)kv->str, SIZEOF_SHA384); + break; + case REPOKEY_TYPE_SHA512: + data_addblob(xd, (unsigned char *)kv->str, SIZEOF_SHA512); + break; case REPOKEY_TYPE_U32: u32 = kv->num; v[0] = u32 >> 24; @@ -785,7 +847,7 @@ repo_write_adddata(struct cbdata *cbdata, Repodata *data, Repokey *key, KeyValue data_addblob(xd, v, 4); break; case REPOKEY_TYPE_NUM: - data_addid(xd, kv->num); + data_addid64(xd, kv->num, kv->num2); break; case REPOKEY_TYPE_DIR: id = kv->id; @@ -813,8 +875,15 @@ repo_write_adddata(struct cbdata *cbdata, Repodata *data, Repokey *key, KeyValue if (cbdata->owndirpool) id = putinowndirpool(cbdata, data, &data->dirpool, id); id = cbdata->dirused[id]; + if (cbdata->filelistmode > 0) + { + xd->len += data_addideof_len(id) + strlen(kv->str) + 1; + break; + } data_addideof(xd, id, kv->eof); data_addblob(xd, (unsigned char *)kv->str, strlen(kv->str) + 1); + if (cbdata->filelistmode < 0) + return 0; break; case REPOKEY_TYPE_FIXARRAY: if (kv->eof == 0) @@ -846,8 +915,8 @@ repo_write_adddata(struct cbdata *cbdata, Repodata *data, Repokey *key, KeyValue } break; default: - fprintf(stderr, "unknown type for %d: %d\n", key->name, key->type); - exit(1); + cbdata->target->error = pool_error(cbdata->repo->pool, -1, "unknown type for %d: %d\n", key->name, key->type); + break; } if (cbdata->target->keys[rm].storage == KEY_STORAGE_VERTICAL_OFFSET && kv->eof) { @@ -905,7 +974,7 @@ traverse_dirs(Dirpool *dp, Id *dirmap, Id n, Id dir, Id *used) } static void -write_compressed_page(FILE *fp, unsigned char *page, int len) +write_compressed_page(Repodata *data, unsigned char *page, int len) { int clen; unsigned char cpage[REPOPAGE_BLOBSIZE]; @@ -913,13 +982,13 @@ write_compressed_page(FILE *fp, unsigned char *page, int len) clen = repopagestore_compress_page(page, len, cpage, len - 1); if (!clen) { - write_u32(fp, len * 2); - write_blob(fp, page, len); + write_u32(data, len * 2); + write_blob(data, page, len); } else { - write_u32(fp, clen * 2 + 1); - write_blob(fp, cpage, clen); + write_u32(data, clen * 2 + 1); + write_blob(data, cpage, clen); } } @@ -931,6 +1000,14 @@ static Id verticals[] = { SOLVABLE_EULA, SOLVABLE_DISKUSAGE, SOLVABLE_FILELIST, + SOLVABLE_CHECKSUM, + DELTA_CHECKSUM, + DELTA_SEQ_NUM, + SOLVABLE_PKGID, + SOLVABLE_HDRID, + SOLVABLE_LEADSIGID, + SOLVABLE_CHANGELOG_AUTHOR, + SOLVABLE_CHANGELOG_TEXT, 0 }; @@ -960,6 +1037,47 @@ repo_write_stdkeyfilter(Repo *repo, Repokey *key, void *kfdata) } /* + * return true if the repodata contains the filelist (and just + * the filelist). The same code is used in the dataiterator. The way + * it is used is completely wrong, of course, as having the filelist + * key does not mean it is used for a specific solvable. Nevertheless + * it is better to have it than to write broken solv files. + */ +static inline int +is_filelist_extension(Repodata *data) +{ + int j; + for (j = 1; j < data->nkeys; j++) + if (data->keys[j].name != REPOSITORY_SOLVABLES && data->keys[j].name != SOLVABLE_FILELIST) + return 0; + return 1; +} + + +static int +write_compressed_extdata(Repodata *target, struct extdata *xd, unsigned char *vpage, int lpage) +{ + unsigned char *dp = xd->buf; + int l = xd->len; + while (l) + { + int ll = REPOPAGE_BLOBSIZE - lpage; + if (l < ll) + ll = l; + memcpy(vpage + lpage, dp, ll); + dp += ll; + lpage += ll; + l -= ll; + if (lpage == REPOPAGE_BLOBSIZE) + { + write_compressed_page(target, vpage, lpage); + lpage = 0; + } + } + return lpage; +} + +/* * Repo */ @@ -975,10 +1093,10 @@ repo_write_stdkeyfilter(Repo *repo, Repokey *key, void *kfdata) * 5) write everything to disk */ int -repo_write(Repo *repo, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *key, void *kfdata), void *kfdata, Queue *keyq) +repo_write_filtered(Repo *repo, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *key, void *kfdata), void *kfdata, Queue *keyq) { Pool *pool = repo->pool; - int i, j, n; + int i, j, n, lastfilelistn; Solvable *s; NeedId *needid; int nstrings, nrels; @@ -995,7 +1113,7 @@ repo_write(Repo *repo, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *key, void unsigned char *repodataused; int anyrepodataused = 0; int anysolvableused = 0; - + struct cbdata cbdata; int clonepool; Repokey *key; @@ -1015,10 +1133,6 @@ repo_write(Repo *repo, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *key, void Id type_constantid = REPOKEY_TYPE_CONSTANTID; - unsigned char *prefixcomp; - unsigned int compsum; - char *old_str; - memset(&cbdata, 0, sizeof(cbdata)); cbdata.repo = repo; @@ -1053,7 +1167,7 @@ repo_write(Repo *repo, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *key, void else if (i < RPM_RPMDBID) keyd.type = REPOKEY_TYPE_REL_IDARRAY; else - keyd.type = REPOKEY_TYPE_U32; + keyd.type = REPOKEY_TYPE_NUM; keyd.size = 0; keyd.storage = KEY_STORAGE_SOLVABLE; if (keyfilter) @@ -1084,6 +1198,7 @@ repo_write(Repo *repo, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *key, void dirpool = 0; dirpooldata = 0; n = ID_NUM_INTERNAL; + lastfilelistn = 0; FOR_REPODATAS(repo, i, data) { cbdata.keymapstart[i] = n; @@ -1174,6 +1289,20 @@ repo_write(Repo *repo, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *key, void idused = 1; /* dirs also use ids */ dirused = 1; } + if (key->type == REPOKEY_TYPE_DIRSTRARRAY && key->name == SOLVABLE_FILELIST) + { + /* is this a file list extension */ + if (is_filelist_extension(data)) + { + /* hmm, we have a file list extension. Kill filelist of other repodata. + * XXX: this is wrong, as the extension does not need to cover all + * solvables of the other repodata */ + if (lastfilelistn) + cbdata.keymap[lastfilelistn] = 0; + } + else + lastfilelistn = n; + } } if (idused) { @@ -1647,6 +1776,19 @@ fprintf(stderr, "dir %d used %d\n", i, cbdata.dirused ? cbdata.dirused[i] : 1); { data_addid(xd, repo->nsolvables); /* FLEXARRAY nentries */ cbdata.doingsolvables = 1; + + /* check if we can do the special filelist memory optimization */ + if (anyrepodataused) + { + for (i = 1; i < target.nkeys; i++) + if (target.keys[i].storage == KEY_STORAGE_VERTICAL_OFFSET) + cbdata.filelistmode |= cbdata.filelistmode == 0 && target.keys[i].type == REPOKEY_TYPE_DIRSTRARRAY ? 1 : 2; + else if (target.keys[i].type == REPOKEY_TYPE_DIRSTRARRAY) + cbdata.filelistmode = 2; + if (cbdata.filelistmode != 1) + cbdata.filelistmode = 0; + } + for (i = repo->start, s = pool->solvables + i, n = 0; i < repo->end; i++, s++) { if (s->repo != repo) @@ -1677,7 +1819,7 @@ fprintf(stderr, "dir %d used %d\n", i, cbdata.dirused ? cbdata.dirused[i] : 1); if (s->enhances && cbdata.keymap[SOLVABLE_ENHANCES]) data_addidarray_sort(xd, pool, needid, idarraydata + s->enhances, 0); if (repo->rpmdbid && cbdata.keymap[RPM_RPMDBID]) - data_addu32(xd, repo->rpmdbid[i - repo->start]); + data_addid(xd, repo->rpmdbid[i - repo->start]); if (anyrepodataused) { cbdata.vstart = -1; @@ -1707,101 +1849,68 @@ fprintf(stderr, "dir %d used %d\n", i, cbdata.dirused ? cbdata.dirused[i] : 1); /********************************************************************/ + target.fp = fp; + /* write header */ /* write file header */ - write_u32(fp, 'S' << 24 | 'O' << 16 | 'L' << 8 | 'V'); - write_u32(fp, SOLV_VERSION_8); + write_u32(&target, 'S' << 24 | 'O' << 16 | 'L' << 8 | 'V'); + write_u32(&target, SOLV_VERSION_8); /* write counts */ - write_u32(fp, nstrings); - write_u32(fp, nrels); - write_u32(fp, ndirmap); - write_u32(fp, anysolvableused ? repo->nsolvables : 0); - write_u32(fp, target.nkeys); - write_u32(fp, target.nschemata); + write_u32(&target, nstrings); + write_u32(&target, nrels); + write_u32(&target, ndirmap); + write_u32(&target, anysolvableused ? repo->nsolvables : 0); + write_u32(&target, target.nkeys); + write_u32(&target, target.nschemata); solv_flags = 0; solv_flags |= SOLV_FLAG_PREFIX_POOL; - write_u32(fp, solv_flags); + solv_flags |= SOLV_FLAG_SIZE_BYTES; + write_u32(&target, solv_flags); - /* - * calculate prefix encoding of the strings - */ - prefixcomp = solv_malloc(nstrings); - compsum = 0; - old_str = ""; - - prefixcomp[0] = 0; - for (i = 1; i < nstrings; i++) - { - char *str = spool->stringspace + spool->strings[needid[i].map]; - int same; - for (same = 0; same < 255; same++) - if (!old_str[same] || old_str[same] != str[same]) - break; - prefixcomp[i] = same; - compsum += same; - old_str = str; - } - - /* - * write strings - */ - write_u32(fp, sizeid); - /* we save compsum bytes but need 1 extra byte for every string */ - write_u32(fp, sizeid + (nstrings ? nstrings - 1 : 0) - compsum); - if (sizeid + (nstrings ? nstrings - 1 : 0) != compsum) + if (nstrings) { + /* + * calculate prefix encoding of the strings + */ + unsigned char *prefixcomp = solv_malloc(nstrings); + unsigned int compsum = 0; + char *old_str = ""; + + prefixcomp[0] = 0; for (i = 1; i < nstrings; i++) { char *str = spool->stringspace + spool->strings[needid[i].map]; - write_u8(fp, prefixcomp[i]); - write_str(fp, str + prefixcomp[i]); + int same; + for (same = 0; same < 255; same++) + if (!old_str[same] || old_str[same] != str[same]) + break; + prefixcomp[i] = same; + compsum += same; + old_str = str; } - } - solv_free(prefixcomp); -#if 0 - /* Build the prefix-encoding of the string pool. We need to know - the size of that before writing it to the file, so we have to - build a separate buffer for that. As it's temporarily possible - that this actually is an expansion we can't easily reuse the - stringspace for this. The max expansion per string is 1 byte, - so it will fit into sizeid+nstrings bytes. */ - char *prefix = solv_malloc(sizeid + nstrings); - char *pp = prefix; - char *old_str = ""; - for (i = 1; i < nstrings; i++) - { - char *str = spool->stringspace + spool->strings[needid[i].map]; - int same; - size_t len; - for (same = 0; same < 255; same++) - if (!old_str[same] || !str[same] || old_str[same] != str[same]) - break; - *pp++ = same; - len = strlen(str + same) + 1; - memcpy(pp, str + same, len); - pp += len; - old_str = str; - } - - /* - * write strings - */ - write_u32(fp, sizeid); - write_u32(fp, pp - prefix); - if (pp != prefix) - { - if (fwrite(prefix, pp - prefix, 1, fp) != 1) + /* + * write strings + */ + write_u32(&target, sizeid); + /* we save compsum bytes but need 1 extra byte for every string */ + write_u32(&target, sizeid + nstrings - 1 - compsum); + for (i = 1; i < nstrings; i++) { - perror("write error prefix"); - exit(1); + char *str = spool->stringspace + spool->strings[needid[i].map]; + write_u8(&target, prefixcomp[i]); + write_str(&target, str + prefixcomp[i]); } + solv_free(prefixcomp); + } + else + { + write_u32(&target, 0); + write_u32(&target, 0); } - solv_free(prefix); -#endif /* * write RelDeps @@ -1809,9 +1918,9 @@ fprintf(stderr, "dir %d used %d\n", i, cbdata.dirused ? cbdata.dirused[i] : 1); for (i = 0; i < nrels; i++) { ran = pool->rels + (needid[reloff + i].map - reloff); - write_id(fp, needid[ISRELDEP(ran->name) ? RELOFF(ran->name) : ran->name].need); - write_id(fp, needid[ISRELDEP(ran->evr) ? RELOFF(ran->evr) : ran->evr].need); - write_u8(fp, ran->flags); + write_id(&target, needid[ISRELDEP(ran->name) ? RELOFF(ran->name) : ran->name].need); + write_id(&target, needid[ISRELDEP(ran->evr) ? RELOFF(ran->evr) : ran->evr].need); + write_u8(&target, ran->flags); } /* @@ -1820,9 +1929,9 @@ fprintf(stderr, "dir %d used %d\n", i, cbdata.dirused ? cbdata.dirused[i] : 1); for (i = 2; i < ndirmap; i++) { if (dirmap[i] > 0) - write_id(fp, dirmap[i]); + write_id(&target, dirmap[i]); else - write_id(fp, nstrings - dirmap[i]); + write_id(&target, nstrings - dirmap[i]); } solv_free(dirmap); @@ -1831,33 +1940,33 @@ fprintf(stderr, "dir %d used %d\n", i, cbdata.dirused ? cbdata.dirused[i] : 1); */ for (i = 1; i < target.nkeys; i++) { - write_id(fp, needid[target.keys[i].name].need); - write_id(fp, needid[target.keys[i].type].need); + write_id(&target, needid[target.keys[i].name].need); + write_id(&target, needid[target.keys[i].type].need); if (target.keys[i].storage != KEY_STORAGE_VERTICAL_OFFSET) { if (target.keys[i].type == type_constantid) - write_id(fp, needid[target.keys[i].size].need); + write_id(&target, needid[target.keys[i].size].need); else - write_id(fp, target.keys[i].size); + write_id(&target, target.keys[i].size); } else - write_id(fp, cbdata.extdata[i].len); - write_id(fp, target.keys[i].storage); + write_id(&target, cbdata.extdata[i].len); + write_id(&target, target.keys[i].storage); } /* * write schemata */ - write_id(fp, target.schemadatalen); /* XXX -1? */ + write_id(&target, target.schemadatalen); /* XXX -1? */ for (i = 1; i < target.nschemata; i++) - write_idarray(fp, pool, 0, repodata_id2schema(&target, i)); + write_idarray(&target, pool, 0, repodata_id2schema(&target, i)); /********************************************************************/ - write_id(fp, cbdata.maxdata); - write_id(fp, cbdata.extdata[0].len); + write_id(&target, cbdata.maxdata); + write_id(&target, cbdata.extdata[0].len); if (cbdata.extdata[0].len) - write_blob(fp, cbdata.extdata[0].buf, cbdata.extdata[0].len); + write_blob(&target, cbdata.extdata[0].buf, cbdata.extdata[0].len); solv_free(cbdata.extdata[0].buf); /* do we have vertical data? */ @@ -1867,40 +1976,56 @@ fprintf(stderr, "dir %d used %d\n", i, cbdata.dirused ? cbdata.dirused[i] : 1); if (i < target.nkeys) { /* yes, write it in pages */ - unsigned char *dp, vpage[REPOPAGE_BLOBSIZE]; - int l, ll, lpage = 0; + unsigned char vpage[REPOPAGE_BLOBSIZE]; + int lpage = 0; - write_u32(fp, REPOPAGE_BLOBSIZE); + write_u32(&target, REPOPAGE_BLOBSIZE); for (i = 1; i < target.nkeys; i++) + if (cbdata.extdata[i].len) + { + if (cbdata.filelistmode) + break; + lpage = write_compressed_extdata(&target, cbdata.extdata + i, vpage, lpage); + } + if (cbdata.filelistmode && i < target.nkeys) { - if (!cbdata.extdata[i].len) - continue; - l = cbdata.extdata[i].len; - dp = cbdata.extdata[i].buf; - while (l) + /* ok, just this single extdata, which is a filelist */ + xd = cbdata.extdata + i; + xd->len = 0; + cbdata.filelistmode = -1; + for (j = 0; j < cbdata.nkeymap; j++) + if (cbdata.keymap[j] != i) + cbdata.keymap[j] = 0; + for (i = repo->start, s = pool->solvables + i; i < repo->end; i++, s++) { - ll = REPOPAGE_BLOBSIZE - lpage; - if (l < ll) - ll = l; - memcpy(vpage + lpage, dp, ll); - dp += ll; - lpage += ll; - l -= ll; - if (lpage == REPOPAGE_BLOBSIZE) + if (s->repo != repo) + continue; + FOR_REPODATAS(repo, j, data) { - write_compressed_page(fp, vpage, lpage); - lpage = 0; + if (!repodataused[j]) + continue; + if (i < data->start || i >= data->end) + continue; + repodata_search(data, i, 0, SEARCH_SUB|SEARCH_ARRAYSENTINEL, repo_write_cb_adddata, &cbdata); + } + if (xd->len > 1024 * 1024) + { + lpage = write_compressed_extdata(&target, xd, vpage, lpage); + xd->len = 0; } } + if (xd->len) + lpage = write_compressed_extdata(&target, xd, vpage, lpage); } if (lpage) - write_compressed_page(fp, vpage, lpage); + write_compressed_page(&target, vpage, lpage); } for (i = 1; i < target.nkeys; i++) solv_free(cbdata.extdata[i].buf); solv_free(cbdata.extdata); + target.fp = 0; repodata_freedata(&target); solv_free(needid); @@ -1911,7 +2036,7 @@ fprintf(stderr, "dir %d used %d\n", i, cbdata.dirused ? cbdata.dirused[i] : 1); solv_free(cbdata.keymapstart); solv_free(cbdata.dirused); solv_free(repodataused); - return 0; + return target.error; } struct repodata_write_data { @@ -1936,12 +2061,24 @@ repodata_write_keyfilter(Repo *repo, Repokey *key, void *kfdata) } int -repodata_write(Repodata *data, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *key, void *kfdata), void *kfdata) +repodata_write_filtered(Repodata *data, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *key, void *kfdata), void *kfdata, Queue *keyq) { struct repodata_write_data wd; wd.keyfilter = keyfilter; wd.kfdata = kfdata; wd.repodataid = data->repodataid; - return repo_write(data->repo, fp, repodata_write_keyfilter, &wd, 0); + return repo_write_filtered(data->repo, fp, repodata_write_keyfilter, &wd, keyq); +} + +int +repodata_write(Repodata *data, FILE *fp) +{ + return repodata_write_filtered(data, fp, repo_write_stdkeyfilter, 0, 0); +} + +int +repo_write(Repo *repo, FILE *fp) +{ + return repo_write_filtered(repo, fp, repo_write_stdkeyfilter, 0, 0); }