From a9aced283d268928888b2e6acdb0ce72bd56b42e Mon Sep 17 00:00:00 2001 From: Michael Schroeder Date: Wed, 19 Mar 2008 18:22:35 +0000 Subject: [PATCH] - write info block containing addedprovides - do not load filelist in addfileproviders if the provides are already there - fix some mem leaks --- src/knownid.h | 2 + src/pool.c | 108 +++++++++++++++++++++++++++++++++++++++++++-------- src/pool.h | 1 + src/repo_solv.c | 53 ++++++++++++++++++------- src/repodata.c | 2 + src/repodata.h | 1 + src/solver.c | 1 + src/util.h | 7 ++++ tools/common_write.c | 34 ++++++++++------ tools/dumpsolv.c | 6 +++ tools/repo_write.c | 106 +++++++++++++++++++++++++++----------------------- tools/repo_write.h | 1 + 12 files changed, 232 insertions(+), 90 deletions(-) diff --git a/src/knownid.h b/src/knownid.h index f3ea72f..2346fc2 100644 --- a/src/knownid.h +++ b/src/knownid.h @@ -48,9 +48,11 @@ KNOWNID(SYSTEM_SYSTEM, "system:system"), KNOWNID(ARCH_SRC, "src"), KNOWNID(ARCH_NOSRC, "nosrc"), KNOWNID(ARCH_NOARCH, "noarch"), +KNOWNID(REPODATA_INFO, "repodata:info"), KNOWNID(REPODATA_EXTERNAL, "repodata:external"), KNOWNID(REPODATA_KEYS, "repodata:keys"), KNOWNID(REPODATA_LOCATION, "repodata:location"), +KNOWNID(REPODATA_ADDEDFILEPROVIDES, "repodata:addedfileprovides"), /* The void type is usable to encode one-valued attributes, they have no associated data. This is useful to encode values which many solvables diff --git a/src/pool.c b/src/pool.c index 422e1d5..5caa887 100644 --- a/src/pool.c +++ b/src/pool.c @@ -647,7 +647,7 @@ pool_addfileprovides_dep(Pool *pool, Id *ida, struct searchfiles *sf, struct sea s = id2str(pool, dep); if (*s != '/') continue; - sf->ids = sat_extend(sf->ids, sf->nfiles, 1, sizeof(const char *), SEARCHFILES_BLOCK); + sf->ids = sat_extend(sf->ids, sf->nfiles, 1, sizeof(Id), SEARCHFILES_BLOCK); sf->dirs = sat_extend(sf->dirs, sf->nfiles, 1, sizeof(const char *), SEARCHFILES_BLOCK); sf->names = sat_extend(sf->names, sf->nfiles, 1, sizeof(const char *), SEARCHFILES_BLOCK); sf->ids[sf->nfiles] = dep; @@ -706,8 +706,80 @@ addfileprovides_cb(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyV return 0; } + +static void +pool_addfileprovides_search(Pool *pool, struct addfileprovides_cbdata *cbd, struct searchfiles *sf, Repo *repoonly) +{ + Id p, start, end, *idp; + Solvable *s; + Repodata *data = 0, *nextdata; + Repo *oldrepo = 0; + int dataincludes = 0; + int i; + Map providedids; + + cbd->nfiles = sf->nfiles; + cbd->ids = sf->ids; + cbd->dirs = sf->dirs; + cbd->names = sf->names; + cbd->olddata = 0; + cbd->dids = sat_realloc2(cbd->dids, sf->nfiles, sizeof(Id)); + if (repoonly) + { + start = repoonly->start; + end = repoonly->end; + } + else + { + start = 2; /* skip system solvable */ + end = pool->nsolvables; + } + for (p = start, s = pool->solvables + p; p < end; p++, s++) + { + if (!s->repo || (repoonly && s->repo != repoonly)) + continue; + if (s->repo != oldrepo || (data && p >= data->end)) + { + data = 0; + oldrepo = 0; + } + if (oldrepo == 0) + { + nextdata = 0; + for (i = 0, data = s->repo->repodata; i < s->repo->nrepodata; i++, data++) + { + if (!data->addedfileprovides || p >= data->end) + continue; + if (!nextdata || nextdata->start > data->start) + nextdata = data; + if (p >= data->start) + break; + } + if (i == s->repo->nrepodata) + data = nextdata; + if (data) + { + map_init(&providedids, pool->ss.nstrings); + for (idp = data->addedfileprovides; *idp; idp++) + MAPSET(&providedids, *idp); + for (i = 0; i < cbd->nfiles; i++) + if (!MAPTST(&providedids, cbd->ids[i])) + { + break; + } + map_free(&providedids); + dataincludes = i == cbd->nfiles; + } + oldrepo = s->repo; + } + if (data && p >= data->start && dataincludes) + continue; + repo_search(s->repo, p, SOLVABLE_FILELIST, 0, 0, addfileprovides_cb, cbd); + } +} + void -pool_addfileprovides(Pool *pool, Repo *installed) +pool_addfileprovides_ids(Pool *pool, Repo *installed, Id **idp) { Solvable *s; Repo *repo; @@ -748,19 +820,22 @@ pool_addfileprovides(Pool *pool, Repo *installed) POOL_DEBUG(SAT_DEBUG_STATS, "found %d installed file dependencies\n", isf.nfiles); cbd.dids = 0; map_init(&cbd.useddirs, 1); + if (idp) + *idp = 0; if (sf.nfiles) { #if 0 for (i = 0; i < sf.nfiles; i++) POOL_DEBUG(SAT_DEBUG_STATS, "looking up %s in filelist\n", id2str(pool, sf.ids[i])); #endif - cbd.nfiles = sf.nfiles; - cbd.ids = sf.ids; - cbd.dirs = sf.dirs; - cbd.names = sf.names; - cbd.olddata = 0; - cbd.dids = sat_realloc2(cbd.dids, sf.nfiles, sizeof(Id)); - pool_search(pool, 0, SOLVABLE_FILELIST, 0, 0, addfileprovides_cb, &cbd); + pool_addfileprovides_search(pool, &cbd, &sf, 0); + if (idp) + { + sf.ids = sat_extend(sf.ids, sf.nfiles, 1, sizeof(Id), SEARCHFILES_BLOCK); + sf.ids[sf.nfiles] = 0; + *idp = sf.ids; + sf.ids = 0; + } sat_free(sf.ids); for (i = 0; i < sf.nfiles; i++) { @@ -776,13 +851,7 @@ pool_addfileprovides(Pool *pool, Repo *installed) for (i = 0; i < isf.nfiles; i++) POOL_DEBUG(SAT_DEBUG_STATS, "looking up %s in installed filelist\n", id2str(pool, isf.ids[i])); #endif - cbd.nfiles = isf.nfiles; - cbd.ids = isf.ids; - cbd.dirs = isf.dirs; - cbd.names = isf.names; - cbd.olddata = 0; - cbd.dids = sat_realloc2(cbd.dids, isf.nfiles, sizeof(Id)); - repo_search(installed, 0, SOLVABLE_FILELIST, 0, 0, addfileprovides_cb, &cbd); + pool_addfileprovides_search(pool, &cbd, &isf, installed); sat_free(isf.ids); for (i = 0; i < isf.nfiles; i++) { @@ -798,6 +867,12 @@ pool_addfileprovides(Pool *pool, Repo *installed) } void +pool_addfileprovides(Pool *pool, Repo *installed) +{ + pool_addfileprovides_ids(pool, installed, 0); +} + +void pool_search(Pool *pool, Id p, Id key, const char *match, int flags, int (*callback)(void *cbdata, Solvable *s, struct _Repodata *data, struct _Repokey *key, struct _KeyValue *kv), void *cbdata) { if (p) @@ -1060,6 +1135,7 @@ pool_calc_duchanges(Pool *pool, Queue *pkgs, DUChanges *mps, int nmps) if (sp < 0) repo_search(pool->solvables[-sp].repo, -sp, SOLVABLE_DISKUSAGE, 0, 0, solver_fill_DU_cb, &cbd); } + sat_free(cbd.dirmap); sat_free(mptree); } diff --git a/src/pool.h b/src/pool.h index 2b0ade6..3331c33 100644 --- a/src/pool.h +++ b/src/pool.h @@ -179,6 +179,7 @@ char * solvable_get_location(Solvable *s, unsigned int *medianrp); */ extern void pool_createwhatprovides(Pool *pool); extern void pool_addfileprovides(Pool *pool, struct _Repo *installed); +extern void pool_addfileprovides_ids(Pool *pool, struct _Repo *installed, Id **idp); extern void pool_freewhatprovides(Pool *pool); extern Id pool_queuetowhatprovides(Pool *pool, Queue *q); diff --git a/src/repo_solv.c b/src/repo_solv.c index 64ade8d..a543dd3 100644 --- a/src/repo_solv.c +++ b/src/repo_solv.c @@ -465,8 +465,9 @@ key_cmp (const void *pa, const void *pb) static void repodata_load_solv(Repodata *data); static void -parse_repodata(Repodata *maindata, Id *keyp, Repokey *keys, Id *idmap, unsigned numid, unsigned numrel, Repo *repo) +parse_external_repodata(Repodata *maindata, Id *keyp, Repokey *keys, Id *idmap, unsigned numid, unsigned numrel) { + Repo *repo = maindata->repo; Id key, id; Id *ida, *ide; Repodata *data; @@ -493,12 +494,12 @@ parse_repodata(Repodata *maindata, Id *keyp, Repokey *keys, Id *idmap, unsigned } /* read_idarray writes a terminating 0, that's why the + 1 */ ida = sat_calloc(keys[key].size + 1, sizeof(Id)); - ide = read_idarray(maindata, 0, 0, ida, ida + keys[key].size + 1); + ide = read_idarray(maindata, numid, idmap, ida, ida + keys[key].size + 1); n = ide - ida - 1; if (n & 1) { pool_debug (mypool, SAT_ERROR, "invalid attribute data\n"); - data->error = SOLV_ERROR_CORRUPT; + maindata->error = SOLV_ERROR_CORRUPT; return; } data->nkeys = 1 + (n >> 1); @@ -506,14 +507,8 @@ parse_repodata(Repodata *maindata, Id *keyp, Repokey *keys, Id *idmap, unsigned memset(data->keys, 0, sizeof(Repokey)); for (i = 1, ide = ida; i < data->nkeys; i++) { - if (*ide >= numid) - { - pool_debug (mypool, SAT_ERROR, "invalid attribute data\n"); - data->error = SOLV_ERROR_CORRUPT; - return; - } - data->keys[i].name = idmap ? idmap[*ide++] : *ide++; - data->keys[i].type = idmap ? idmap[*ide++] : *ide++; + data->keys[i].name = *ide++; + data->keys[i].type = *ide++; data->keys[i].size = 0; data->keys[i].storage = 0; } @@ -542,6 +537,26 @@ parse_repodata(Repodata *maindata, Id *keyp, Repokey *keys, Id *idmap, unsigned } } +static void +parse_info_repodata(Repodata *maindata, Id *keyp, Repokey *keys, Id *idmap, unsigned numid, unsigned numrel) +{ + Id key, id; + Id *ida; + while ((key = *keyp++) != 0) + { + id = keys[key].name; + if (id == REPODATA_ADDEDFILEPROVIDES && keys[key].type == REPOKEY_TYPE_IDARRAY) + { + /* + 1 just in case */ + ida = sat_calloc(keys[key].size + 1, sizeof(Id)); + read_idarray(maindata, numid, idmap, ida, ida + keys[key].size + 1); + maindata->addedfileprovides = ida; + continue; + } + skip_item(maindata, keys[key].type, numid, numrel); + } +} + /*-----------------------------------------------------------------*/ @@ -1127,10 +1142,16 @@ repo_add_solv_parent(Repo *repo, FILE *fp, Repodata *parent) if (keys[key].name == REPODATA_EXTERNAL && keys[key].type == REPOKEY_TYPE_VOID) { /* external data for some ids */ - parse_repodata(&data, keyp, keys, idmap, numid, numrel, repo); + parse_external_repodata(&data, keyp, keys, idmap, numid, numrel); + } + else if (keys[key].name == REPODATA_INFO) + { + parse_info_repodata(&data, keyp, keys, idmap, numid, numrel); } else - skip_schema(&data, keyp, keys, numid, numrel); + { + skip_schema(&data, keyp, keys, numid, numrel); + } } @@ -1189,7 +1210,11 @@ repo_add_solv_parent(Repo *repo, FILE *fp, Repodata *parent) s = 0; if (have_xdata) - repodata_extend_block(&data, data.start, numsolv); + { + /* reserve one byte so that all offsets are not zero */ + incore_add_id(&data, 0); + repodata_extend_block(&data, data.start, numsolv); + } left = 0; buf = sat_calloc(maxsize + 4, 1); diff --git a/src/repodata.c b/src/repodata.c index f974837..1f52a3e 100644 --- a/src/repodata.c +++ b/src/repodata.c @@ -87,6 +87,7 @@ repodata_free(Repodata *data) sat_free(data->attriddata); sat_free(data->location); + sat_free(data->addedfileprovides); if (data->pagefd != -1) close(data->pagefd); @@ -1291,6 +1292,7 @@ repodata_internalize(Repodata *data) nentry = data->end - data->start; addschema_prepare(data, schematacache); memset(&newincore, 0, sizeof(newincore)); + data_addid(&newincore, 0); for (entry = 0; entry < nentry; entry++) { memset(seen, 0, data->nkeys * sizeof(Id)); diff --git a/src/repodata.h b/src/repodata.h index 49d8e0c..8e3ffcd 100644 --- a/src/repodata.h +++ b/src/repodata.h @@ -101,6 +101,7 @@ typedef struct _Repodata { Id *attriddata; /* their id space */ unsigned int attriddatalen; + Id *addedfileprovides; } Repodata; /* Search key (all keys, if keyname == 0) for Id diff --git a/src/solver.c b/src/solver.c index 9364b5a..65f2959 100644 --- a/src/solver.c +++ b/src/solver.c @@ -3911,6 +3911,7 @@ solver_calc_changed_pkgs(Solver *solv, Queue *pkgs) for (p = 1; p < pool->nsolvables; p++) if (MAPTST(&installmap, p)) queue_push(pkgs, p); + map_free(&installmap); /* run through erase solvable dudata */ if (solv->installed) { diff --git a/src/util.h b/src/util.h index cb3b87f..e955c07 100644 --- a/src/util.h +++ b/src/util.h @@ -38,6 +38,13 @@ static inline void *sat_extend(void *buf, size_t len, size_t nmemb, size_t size, return buf; } +static inline void *sat_zextend(void *buf, size_t len, size_t nmemb, size_t size, size_t block) +{ + buf = sat_extend(buf, len, nmemb, size, block); + memset(buf + len * size, 0, nmemb * size); + return buf; +} + static inline void *sat_extend_resize(void *buf, size_t len, size_t size, size_t block) { if (len) diff --git a/tools/common_write.c b/tools/common_write.c index 747388a..c9ea71c 100644 --- a/tools/common_write.c +++ b/tools/common_write.c @@ -143,6 +143,8 @@ keyfilter_other(Repo *repo, Repokey *key, void *kfdata) * If is given, split attributes */ +#define REPODATAFILE_BLOCK 15 + int tool_write(Repo *repo, const char *basename, const char *attrname) { @@ -154,6 +156,10 @@ tool_write(Repo *repo, const char *basename, const char *attrname) int nlanguages = 0; int i, j, k, l; + fileinfos = sat_zextend(fileinfos, nfileinfos, 1, sizeof(Repodatafile), REPODATAFILE_BLOCK); + pool_addfileprovides_ids(repo->pool, 0, &fileinfos[nfileinfos].addedfileprovides); + nfileinfos++; + if (basename) { struct keyfilter_other_data kd; @@ -189,7 +195,7 @@ tool_write(Repo *repo, const char *basename, const char *attrname) languages[nlanguages++] = strdup(keyname + l); } } - fileinfos = sat_calloc(nlanguages + 2, sizeof(Repodatafile)); + fileinfos = sat_zextend(fileinfos, nfileinfos, nlanguages + 2, sizeof(Repodatafile), REPODATAFILE_BLOCK); /* write language subfiles */ for (i = 0; i < nlanguages; i++) { @@ -200,8 +206,9 @@ tool_write(Repo *repo, const char *basename, const char *attrname) exit(1); } repo_write(repo, fp, keyfilter_language, languages[i], fileinfos + nfileinfos, 0); - fileinfos[nfileinfos++].location = strdup(fn); + fileinfos[nfileinfos].location = strdup(fn); fclose(fp); + nfileinfos++; } /* write DU subfile */ if (has_DU) @@ -213,8 +220,9 @@ tool_write(Repo *repo, const char *basename, const char *attrname) exit(1); } repo_write(repo, fp, keyfilter_DU, 0, fileinfos + nfileinfos, 0); - fileinfos[nfileinfos++].location = strdup(fn); + fileinfos[nfileinfos].location = strdup(fn); fclose(fp); + nfileinfos++; } /* write filelist */ if (has_FL) @@ -226,8 +234,9 @@ tool_write(Repo *repo, const char *basename, const char *attrname) exit(1); } repo_write(repo, fp, keyfilter_FL, 0, fileinfos + nfileinfos, 0); - fileinfos[nfileinfos++].location = strdup(fn); + fileinfos[nfileinfos].location = strdup(fn); fclose(fp); + nfileinfos++; } /* write everything else */ sprintf(fn, "%s.solv", basename); @@ -245,6 +254,7 @@ tool_write(Repo *repo, const char *basename, const char *attrname) sat_free(languages); for (i = 0; i < nfileinfos; i++) { + sat_free(fileinfos[i].addedfileprovides); sat_free(fileinfos[i].location); sat_free(fileinfos[i].keys); } @@ -253,19 +263,21 @@ tool_write(Repo *repo, const char *basename, const char *attrname) } if (attrname) { - fileinfos = sat_calloc(1, sizeof(Repodatafile)); + fileinfos = sat_zextend(fileinfos, nfileinfos, 1, sizeof(Repodatafile), REPODATAFILE_BLOCK); test_separate = 1; FILE *fp = fopen (attrname, "w"); - repo_write(repo, fp, keyfilter_attr, 0, fileinfos + nfileinfos++, 0); - fileinfos[nfileinfos - 1].location = strdup(attrname); + repo_write(repo, fp, keyfilter_attr, 0, fileinfos + nfileinfos, 0); + fileinfos[nfileinfos].location = strdup(attrname); fclose(fp); + nfileinfos++; } repo_write(repo, stdout, keyfilter_solv, 0, fileinfos, nfileinfos); - if (fileinfos) + for (i = 0; i < nfileinfos; i++) { - free(fileinfos[0].location); - free(fileinfos[0].keys); - free(fileinfos); + sat_free(fileinfos[i].addedfileprovides); + sat_free(fileinfos[i].location); + sat_free(fileinfos[i].keys); } + sat_free(fileinfos); return 0; } diff --git a/tools/dumpsolv.c b/tools/dumpsolv.c index c33a21e..69b84c7 100644 --- a/tools/dumpsolv.c +++ b/tools/dumpsolv.c @@ -33,6 +33,12 @@ dump_repodata (Repo *repo) printf(" localpool has %d strings, size is %d\n", data->spool.nstrings, data->spool.sstrings); if (data->dirpool.ndirs) printf(" localpool has %d directories\n", data->dirpool.ndirs); + if (data->addedfileprovides) + { + printf(" added file provides:\n"); + for (j = 0; data->addedfileprovides[j]; j++) + printf(" %s\n", id2str(repo->pool, data->addedfileprovides[j])); + } printf("\n"); } printf("\n"); diff --git a/tools/repo_write.c b/tools/repo_write.c index 26ec556..2a17c18 100644 --- a/tools/repo_write.c +++ b/tools/repo_write.c @@ -850,8 +850,7 @@ repo_write(Repo *repo, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *key, void Dirpool owndirpool, *dirpool; int setfileinfo = 0; - Id repodataschema = 0; - Id repodataschema_internal = 0; + Id *repodataschemata = 0; struct extdata *xd; @@ -863,6 +862,8 @@ repo_write(Repo *repo, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *key, void writing a subfile and our callers wants info about it. */ if (fileinfo && nsubfiles == 0) setfileinfo = 1; + if (nsubfiles) + repodataschemata = sat_calloc(nsubfiles, sizeof(Id)); memset(&cbdata, 0, sizeof(cbdata)); cbdata.repo = repo; @@ -912,32 +913,43 @@ repo_write(Repo *repo, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *key, void } cbdata.nmykeys = i; - /* If we store subfile info, generate the three necessary keys. */ + /* If we store subfile info, generate the necessary keys. */ if (nsubfiles) { key = cbdata.mykeys + cbdata.nmykeys; + key->name = REPODATA_INFO; + key->type = REPOKEY_TYPE_VOID; + key->size = 0; + key->storage = KEY_STORAGE_SOLVABLE; + cbdata.keymap[key->name] = cbdata.nmykeys++; + + key = cbdata.mykeys + cbdata.nmykeys; key->name = REPODATA_EXTERNAL; key->type = REPOKEY_TYPE_VOID; key->size = 0; key->storage = KEY_STORAGE_SOLVABLE; - cbdata.keymap[key->name] = key - cbdata.mykeys; - key++; + cbdata.keymap[key->name] = cbdata.nmykeys++; + key = cbdata.mykeys + cbdata.nmykeys; key->name = REPODATA_KEYS; key->type = REPOKEY_TYPE_IDARRAY; key->size = 0; key->storage = KEY_STORAGE_SOLVABLE; - cbdata.keymap[key->name] = key - cbdata.mykeys; - key++; + cbdata.keymap[key->name] = cbdata.nmykeys++; + key = cbdata.mykeys + cbdata.nmykeys; key->name = REPODATA_LOCATION; key->type = REPOKEY_TYPE_STR; key->size = 0; key->storage = KEY_STORAGE_SOLVABLE; - cbdata.keymap[key->name] = key - cbdata.mykeys; - key++; + cbdata.keymap[key->name] = cbdata.nmykeys++; - cbdata.nmykeys = key - cbdata.mykeys; + key = cbdata.mykeys + cbdata.nmykeys; + key->name = REPODATA_ADDEDFILEPROVIDES; + key->type = REPOKEY_TYPE_IDARRAY; + key->size = 0; + key->storage = KEY_STORAGE_SOLVABLE; + cbdata.keymap[key->name] = cbdata.nmykeys++; } dirpoolusage = 0; @@ -1095,7 +1107,7 @@ fprintf(stderr, "poolusage: %d\n", poolusage); fprintf(stderr, "dirpoolusage: %d\n", dirpoolusage); fprintf(stderr, "nmykeys: %d\n", cbdata.nmykeys); for (i = 1; i < cbdata.nmykeys; i++) - fprintf(stderr, " %2d: %d %d %d %d\n", i, cbdata.mykeys[i].name, cbdata.mykeys[i].type, cbdata.mykeys[i].size, cbdata.mykeys[i].storage); + fprintf(stderr, " %2d: %s[%d] %d %d %d\n", i, id2str(pool, cbdata.mykeys[i].name), cbdata.mykeys[i].name, cbdata.mykeys[i].type, cbdata.mykeys[i].size, cbdata.mykeys[i].storage); #endif /********************************************************************/ @@ -1220,44 +1232,34 @@ for (i = 1; i < cbdata.nmykeys; i++) for (i = 0; i < nsubfiles; i++) { int j; + Id schema[4], *sp; - if (fileinfo[i].location && !repodataschema) - { - Id schema[4]; - schema[0] = cbdata.keymap[REPODATA_EXTERNAL]; - schema[1] = cbdata.keymap[REPODATA_KEYS]; - schema[2] = cbdata.keymap[REPODATA_LOCATION]; - schema[3] = 0; - repodataschema = addschema(&cbdata, schema); + sp = schema; + if (fileinfo[i].addedfileprovides) + { + /* extra info about this file */ + *sp++ = cbdata.keymap[REPODATA_INFO]; + *sp++ = cbdata.keymap[REPODATA_ADDEDFILEPROVIDES]; + for (j = 0; fileinfo[i].addedfileprovides[j]; j++) + j++; + cbdata.mykeys[cbdata.keymap[REPODATA_ADDEDFILEPROVIDES]].size += j + 1; } - else if (!repodataschema_internal) - { - Id schema[3]; - schema[0] = cbdata.keymap[REPODATA_EXTERNAL]; - schema[1] = cbdata.keymap[REPODATA_KEYS]; - schema[2] = 0; - repodataschema_internal = addschema(&cbdata, schema); + else + { + *sp++ = cbdata.keymap[REPODATA_EXTERNAL]; + *sp++ = cbdata.keymap[REPODATA_KEYS]; + if (fileinfo[i].location) + *sp++ = cbdata.keymap[REPODATA_LOCATION]; } - if (2 * fileinfo[i].nkeys > cbdata.mykeys[cbdata.keymap[REPODATA_KEYS]].size) - cbdata.mykeys[cbdata.keymap[REPODATA_KEYS]].size = 2 * fileinfo[i].nkeys; + *sp = 0; + repodataschemata[i] = addschema(&cbdata, schema); + cbdata.mykeys[cbdata.keymap[REPODATA_KEYS]].size += 2 * fileinfo[i].nkeys + 1; for (j = 1; j < fileinfo[i].nkeys; j++) { needid[fileinfo[i].keys[j].type].need++; needid[fileinfo[i].keys[j].name].need++; } -#if 0 - fprintf (stderr, " %d nkeys: %d:", i, fileinfo[i].nkeys); - for (j = 1; j < fileinfo[i].nkeys; j++) - { - needid[fileinfo[i].keys[j].name].need++; - fprintf (stderr, " %s(%d,%d)", id2str(pool, fileinfo[i].keys[j].name), - fileinfo[i].keys[j].name, fileinfo[i].keys[j].type); - } - fprintf (stderr, "\n"); -#endif } - if (nsubfiles) - cbdata.mykeys[cbdata.keymap[REPODATA_KEYS]].size -= 2; /********************************************************************/ @@ -1601,18 +1603,23 @@ fprintf(stderr, "dir %d used %d\n", i, cbdata.dirused ? cbdata.dirused[i] : 1); int j; cur = xd.len; - if (fileinfo[i].location) - data_addid(&xd, repodataschema); + data_addid(&xd, repodataschemata[i]); + if (fileinfo[i].addedfileprovides) + { + for (j = 0; fileinfo[i].addedfileprovides[j]; j++) + data_addideof(&xd, needid[fileinfo[i].addedfileprovides[j]].need, fileinfo[i].addedfileprovides[j + 1] ? 0 : 1); + } else - data_addid(&xd, repodataschema_internal); - /* key,type array + location, write idarray */ - for (j = 1; j < fileinfo[i].nkeys; j++) { - data_addideof(&xd, needid[fileinfo[i].keys[j].name].need, 0); - data_addideof(&xd, needid[fileinfo[i].keys[j].type].need, j == fileinfo[i].nkeys - 1); + /* key,type array + location, write idarray */ + for (j = 1; j < fileinfo[i].nkeys; j++) + { + data_addideof(&xd, needid[fileinfo[i].keys[j].name].need, 0); + data_addideof(&xd, needid[fileinfo[i].keys[j].type].need, j == fileinfo[i].nkeys - 1); + } + if (fileinfo[i].location) + data_addblob(&xd, (unsigned char *)fileinfo[i].location, strlen(fileinfo[i].location) + 1); } - if (fileinfo[i].location) - data_addblob(&xd, (unsigned char *)fileinfo[i].location, strlen(fileinfo[i].location) + 1); cur = xd.len - cur; if (cur > max) max = cur; @@ -1716,4 +1723,5 @@ fprintf(stderr, "dir %d used %d\n", i, cbdata.dirused ? cbdata.dirused[i] : 1); sat_free(cbdata.keymapstart); sat_free(cbdata.dirused); sat_free(repodataused); + sat_free(repodataschemata); } diff --git a/tools/repo_write.h b/tools/repo_write.h index 149eb3e..0d9d51d 100644 --- a/tools/repo_write.h +++ b/tools/repo_write.h @@ -29,6 +29,7 @@ typedef struct _Repodatafile unsigned checksumtype; struct _Repokey *keys; unsigned int nkeys; + Id *addedfileprovides; } Repodatafile; void repo_write(Repo *repo, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *key, void *kfdata), void *kfdata, Repodatafile *fileinfo, int nsubfiles); -- 2.7.4