X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Frepodata.c;h=55517c58f2ac0d5f1b3baa0200e44c5522cca9de;hb=f81272c390895e768150a7750d6a1e42c06488e9;hp=e256245b464416fd6623f5919b1017c7e85053aa;hpb=453c586e7d0d64c1162993fd7f70ec18d5e2f694;p=platform%2Fupstream%2Flibsolv.git diff --git a/src/repodata.c b/src/repodata.c index e256245..55517c5 100644 --- a/src/repodata.c +++ b/src/repodata.c @@ -34,15 +34,9 @@ #include "repopack.h" #include "repopage.h" -extern unsigned int compress_buf (const unsigned char *in, unsigned int in_len, - unsigned char *out, unsigned int out_len); -extern unsigned int unchecked_decompress_buf (const unsigned char *in, - unsigned int in_len, - unsigned char *out, - unsigned int out_len); - #define REPODATA_BLOCK 255 +static unsigned char *data_skip_key(Repodata *data, unsigned char *dp, Repokey *key); void repodata_initdata(Repodata *data, Repo *repo, int localpool) @@ -52,6 +46,7 @@ repodata_initdata(Repodata *data, Repo *repo, int localpool) data->localpool = localpool; if (localpool) stringpool_init_empty(&data->spool); + /* dirpool_init(&data->dirpool); just zeros out again */ data->keys = sat_calloc(1, sizeof(Repokey)); data->nkeys = 1; data->schemata = sat_calloc(1, sizeof(Id)); @@ -116,10 +111,21 @@ repodata_free(Repodata *data) int i = data - repo->repodata; repodata_freedata(data); if (i < repo->nrepodata - 1) - memmove(repo->repodata + i, repo->repodata + i + 1, (repo->nrepodata - 1 - i) * sizeof(Repodata)); + memmove(repo->repodata + i, repo->repodata + i + 1, (repo->nrepodata - 1 - i) * sizeof(Repodata)); repo->nrepodata--; } +void +repodata_empty(Repodata *data, int localpool) +{ + void (*loadcallback)(Repodata *) = data->loadcallback; + int state = data->state; + repodata_freedata(data); + repodata_initdata(data, data->repo, localpool); + data->state = state; + data->loadcallback = loadcallback; +} + /*************************************************************** * key pool management @@ -171,15 +177,17 @@ repodata_schema2id(Repodata *data, Id *schema, int create) Id *sp, cid; Id *schematahash; + if (!*schema) + return 0; /* XXX: allow empty schema? */ if ((schematahash = data->schematahash) == 0) { data->schematahash = schematahash = sat_calloc(256, sizeof(Id)); - for (i = 0; i < data->nschemata; i++) + for (i = 1; i < data->nschemata; i++) { for (sp = data->schemadata + data->schemata[i], h = 0; *sp; len++) h = h * 7 + *sp++; h &= 255; - schematahash[h] = i + 1; + schematahash[h] = i; } data->schemadata = sat_extend_resize(data->schemadata, data->schemadatalen, sizeof(Id), SCHEMATADATA_BLOCK); data->schemata = sat_extend_resize(data->schemata, data->nschemata, sizeof(Id), SCHEMATA_BLOCK); @@ -193,11 +201,10 @@ repodata_schema2id(Repodata *data, Id *schema, int create) cid = schematahash[h]; if (cid) { - cid--; if (!memcmp(data->schemadata + data->schemata[cid], schema, len * sizeof(Id))) return cid; - /* cache conflict */ - for (cid = 0; cid < data->nschemata; cid++) + /* cache conflict, do a slow search */ + for (cid = 1; cid < data->nschemata; cid++) if (!memcmp(data->schemadata + data->schemata[cid], schema, len * sizeof(Id))) return cid; } @@ -210,7 +217,7 @@ repodata_schema2id(Repodata *data, Id *schema, int create) memcpy(data->schemadata + data->schemadatalen, schema, len * sizeof(Id)); data->schemata[data->nschemata] = data->schemadatalen; data->schemadatalen += len; - schematahash[h] = data->nschemata + 1; + schematahash[h] = data->nschemata; #if 0 fprintf(stderr, "schema2id: new schema\n"); #endif @@ -231,6 +238,14 @@ repodata_free_schemahash(Repodata *data) * dir pool management */ +#ifndef HAVE_STRCHRNUL +static inline const char *strchrnul(const char *str, char x) +{ + const char *p = strchr(str, x); + return p ? p : str + strlen(str); +} +#endif + Id repodata_str2dir(Repodata *data, const char *dir, int create) { @@ -241,14 +256,18 @@ repodata_str2dir(Repodata *data, const char *dir, int create) while (*dir == '/' && dir[1] == '/') dir++; if (*dir == '/' && !dir[1]) - return 1; + { + if (data->dirpool.ndirs) + return 1; + return dirpool_add_dir(&data->dirpool, 0, 1, create); + } while (*dir) { dire = strchrnul(dir, '/'); if (data->localpool) id = stringpool_strn2id(&data->spool, dir, dire - dir, create); else - id = strn2id(data->repo->pool, dir, dire - dir, create); + id = pool_strn2id(data->repo->pool, dir, dire - dir, create); if (!id) return 0; parent = dirpool_add_dir(&data->dirpool, parent, id, create); @@ -323,7 +342,7 @@ data_skip_schema(Repodata *data, unsigned char *dp, Id schema) return dp; } -unsigned char * +static unsigned char * data_skip_key(Repodata *data, unsigned char *dp, Repokey *key) { int nentries, schema; @@ -406,10 +425,10 @@ get_vertical_data(Repodata *data, Repokey *key, Id off, Id len) return 0; /* we now have the offset, go into vertical */ off += data->verticaloffset[key - data->keys]; - /* fprintf(stderr, "key %d page %d\n", key->name, off / BLOB_PAGESIZE); */ - dp = repopagestore_load_page_range(&data->store, off / BLOB_PAGESIZE, (off + len - 1) / BLOB_PAGESIZE); + /* fprintf(stderr, "key %d page %d\n", key->name, off / REPOPAGE_BLOBSIZE); */ + dp = repopagestore_load_page_range(&data->store, off / REPOPAGE_BLOBSIZE, (off + len - 1) / REPOPAGE_BLOBSIZE); if (dp) - dp += off % BLOB_PAGESIZE; + dp += off % REPOPAGE_BLOBSIZE; return dp; } @@ -530,6 +549,8 @@ find_key_data(Repodata *data, Id solvid, Id keyname, Repokey **keypp) if (!*kp) return 0; *keypp = key = data->keys + *kp; + if (key->type == REPOKEY_TYPE_DELETED) + return 0; if (key->type == REPOKEY_TYPE_VOID || key->type == REPOKEY_TYPE_CONSTANT || key->type == REPOKEY_TYPE_CONSTANTID) return dp; /* no need to forward... */ dp = forward_to_key(data, *kp, keyp, dp); @@ -538,6 +559,20 @@ find_key_data(Repodata *data, Id solvid, Id keyname, Repokey **keypp) return get_data(data, key, &dp, 0); } +Id +repodata_lookup_type(Repodata *data, Id solvid, Id keyname) +{ + Id schema, *keyp, *kp; + if (!maybe_load_repodata(data, keyname)) + return 0; + if (!solvid2data(data, solvid, &schema)) + return 0; + keyp = data->schemadata + data->schemata[schema]; + for (kp = keyp; *kp; kp++) + if (data->keys[*kp].name == keyname) + return data->keys[*kp].type; + return 0; +} Id repodata_lookup_id(Repodata *data, Id solvid, Id keyname) @@ -557,14 +592,6 @@ repodata_lookup_id(Repodata *data, Id solvid, Id keyname) return id; } -Id -repodata_globalize_id(Repodata *data, Id id, int create) -{ - if (!id || !data || !data->localpool) - return id; - return str2id(data->repo->pool, stringpool_id2str(&data->spool, id), create); -} - const char * repodata_lookup_str(Repodata *data, Id solvid, Id keyname) { @@ -578,14 +605,14 @@ repodata_lookup_str(Repodata *data, Id solvid, Id keyname) if (key->type == REPOKEY_TYPE_STR) return (const char *)dp; if (key->type == REPOKEY_TYPE_CONSTANTID) - return id2str(data->repo->pool, key->size); - if (key->type == REPOKEY_TYPE_ID) + id = key->size; + else if (key->type == REPOKEY_TYPE_ID) dp = data_read_id(dp, &id); else return 0; if (data->localpool) - return data->spool.stringspace + data->spool.strings[id]; - return id2str(data->repo->pool, id); + return stringpool_id2str(&data->spool, id); + return pool_id2str(data->repo->pool, id); } int @@ -603,6 +630,7 @@ repodata_lookup_num(Repodata *data, Id solvid, Id keyname, unsigned int *value) || key->type == REPOKEY_TYPE_U32 || key->type == REPOKEY_TYPE_CONSTANT) { + kv.num = 0; dp = data_fetch(dp, &kv, key); *value = kv.num; return 1; @@ -642,6 +670,46 @@ repodata_lookup_bin_checksum(Repodata *data, Id solvid, Id keyname, Id *typep) return dp; } +int +repodata_lookup_idarray(Repodata *data, Id solvid, Id keyname, Queue *q) +{ + unsigned char *dp; + Repokey *key; + Id id; + int eof = 0; + + queue_empty(q); + dp = find_key_data(data, solvid, keyname, &key); + if (!dp) + return 0; + if (key->type != REPOKEY_TYPE_IDARRAY && key->type != REPOKEY_TYPE_REL_IDARRAY) + return 0; + for (;;) + { + dp = data_read_ideof(dp, &id, &eof); + queue_push(q, id); + if (eof) + break; + } + return 1; +} + +Id +repodata_globalize_id(Repodata *data, Id id, int create) +{ + if (!id || !data || !data->localpool) + return id; + return pool_str2id(data->repo->pool, stringpool_id2str(&data->spool, id), create); +} + +Id +repodata_localize_id(Repodata *data, Id id, int create) +{ + if (!id || !data || !data->localpool) + return id; + return stringpool_str2id(&data->spool, pool_id2str(data->repo->pool, id), create); +} + /************************************************************************ * data search @@ -659,7 +727,7 @@ repodata_stringify(Pool *pool, Repodata *data, Repokey *key, KeyValue *kv, int f if (data && data->localpool) kv->str = stringpool_id2str(&data->spool, kv->id); else - kv->str = id2str(pool, kv->id); + kv->str = pool_id2str(pool, kv->id); if ((flags & SEARCH_SKIP_KIND) != 0 && key->storage == KEY_STORAGE_SOLVABLE) { const char *s; @@ -754,6 +822,8 @@ repodata_search(Repodata *data, Id solvid, Id keyname, int flags, int (*callback key = data->keys + keyid; ddp = get_data(data, key, &dp, *keyp ? 1 : 0); + if (key->type == REPOKEY_TYPE_DELETED) + continue; if (key->type == REPOKEY_TYPE_FLEXARRAY || key->type == REPOKEY_TYPE_FIXARRAY) { struct subschema_data subd; @@ -1106,7 +1176,7 @@ void dataiterator_set_search(Dataiterator *di, Repo *repo, Id p) { di->repo = repo; - di->repoid = -1; + di->repoid = 0; di->flags &= ~SEARCH_THISSOLVID; di->nparents = 0; di->rootlevel = 0; @@ -1118,7 +1188,7 @@ dataiterator_set_search(Dataiterator *di, Repo *repo, Id p) } if (!repo) { - di->repoid = 0; + di->repoid = 1; di->repo = di->pool->repos[0]; } di->state = di_enterrepo; @@ -1184,7 +1254,10 @@ dataiterator_filelistcheck(Dataiterator *di) Repodata *data = di->data; if ((di->matcher.flags & SEARCH_COMPLETE_FILELIST) != 0) - if (!di->matcher.match || (di->matcher.flags & (SEARCH_STRINGMASK|SEARCH_NOCASE)) != SEARCH_STRING || !repodata_filelistfilter_matches(di->data, di->matcher.match)) + if (!di->matcher.match + || ((di->matcher.flags & (SEARCH_STRINGMASK|SEARCH_NOCASE)) != SEARCH_STRING + && (di->matcher.flags & (SEARCH_STRINGMASK|SEARCH_NOCASE)) != SEARCH_GLOB) + || !repodata_filelistfilter_matches(di->data, di->matcher.match)) needcomplete = 1; if (data->state != REPODATA_AVAILABLE) return needcomplete ? 1 : 0; @@ -1265,6 +1338,8 @@ dataiterator_step(Dataiterator *di) di->ddp = get_data(di->data, di->key, &di->dp, di->keyp[1] && (!di->keyname || (di->flags & SEARCH_SUB) != 0) ? 1 : 0); if (!di->ddp) goto di_nextkey; + if (di->key->type == REPOKEY_TYPE_DELETED) + goto di_nextkey; if (di->key->type == REPOKEY_TYPE_FIXARRAY || di->key->type == REPOKEY_TYPE_FLEXARRAY) goto di_enterarray; if (di->nkeynames && di->nparents - di->rootlevel < di->nkeynames) @@ -1308,13 +1383,13 @@ dataiterator_step(Dataiterator *di) /* FALLTHROUGH */ case di_nextrepo: di_nextrepo: - if (di->repoid >= 0) + if (di->repoid > 0) { di->repoid++; di->repodataid = 0; - if (di->repoid < di->pool->nrepos) + if (di->repoid - 1 < di->pool->nrepos) { - di->repo = di->pool->repos[di->repoid]; + di->repo = di->pool->repos[di->repoid - 1]; goto di_enterrepo; } } @@ -1570,6 +1645,7 @@ void dataiterator_skip_solvable(Dataiterator *di) { di->nparents = 0; + di->kv.parent = 0; di->rootlevel = 0; di->keyname = di->keynames[0]; di->state = di_nextsolvable; @@ -1579,6 +1655,7 @@ void dataiterator_skip_repo(Dataiterator *di) { di->nparents = 0; + di->kv.parent = 0; di->rootlevel = 0; di->keyname = di->keynames[0]; di->state = di_nextrepo; @@ -1588,6 +1665,7 @@ void dataiterator_jump_to_solvid(Dataiterator *di, Id solvid) { di->nparents = 0; + di->kv.parent = 0; di->rootlevel = 0; di->keyname = di->keynames[0]; if (solvid == SOLVID_POS) @@ -1598,7 +1676,7 @@ dataiterator_jump_to_solvid(Dataiterator *di, Id solvid) di->state = di_bye; return; } - di->repoid = -1; + di->repoid = 0; di->data = di->repo->repodata + di->pool->pos.repodataid; di->repodataid = -1; di->solvid = solvid; @@ -1609,17 +1687,17 @@ dataiterator_jump_to_solvid(Dataiterator *di, Id solvid) if (solvid > 0) { di->repo = di->pool->solvables[solvid].repo; - di->repoid = -1; + di->repoid = 0; } - else if (di->repoid >= 0) + else if (di->repoid > 0) { if (!di->pool->nrepos) { di->state = di_bye; return; } + di->repoid = 1; di->repo = di->pool->repos[0]; - di->repoid = 0; } di->repodataid = 0; di->solvid = solvid; @@ -1632,9 +1710,10 @@ void dataiterator_jump_to_repo(Dataiterator *di, Repo *repo) { di->nparents = 0; + di->kv.parent = 0; di->rootlevel = 0; di->repo = repo; - di->repoid = -1; + di->repoid = 0; /* 0 means stay at repo */ di->repodataid = 0; di->solvid = 0; di->flags &= ~SEARCH_THISSOLVID; @@ -1743,7 +1822,7 @@ repodata_extend_block(Repodata *data, Id start, Id num) /**********************************************************************/ -#define REPODATA_ATTRS_BLOCK 63 +#define REPODATA_ATTRS_BLOCK 31 #define REPODATA_ATTRDATA_BLOCK 1023 #define REPODATA_ATTRIDDATA_BLOCK 63 @@ -1754,7 +1833,7 @@ repodata_new_handle(Repodata *data) if (!data->nxattrs) { data->xattrs = sat_calloc_block(1, sizeof(Id *), REPODATA_BLOCK); - data->nxattrs = 2; + data->nxattrs = 2; /* -1: SOLVID_META */ } data->xattrs = sat_extend(data->xattrs, data->nxattrs, 1, sizeof(Id *), REPODATA_BLOCK); data->xattrs[data->nxattrs] = 0; @@ -1764,16 +1843,15 @@ repodata_new_handle(Repodata *data) static inline Id ** repodata_get_attrp(Repodata *data, Id handle) { - if (handle == SOLVID_META) + if (handle < 0) { - if (!data->xattrs) + if (handle == SOLVID_META && !data->xattrs) { data->xattrs = sat_calloc_block(1, sizeof(Id *), REPODATA_BLOCK); data->nxattrs = 2; } + return data->xattrs - handle; } - if (handle < 0) - return data->xattrs - handle; if (handle < data->start || handle >= data->end) repodata_extend(data, handle); if (!data->attrs) @@ -1800,7 +1878,7 @@ repodata_insert_keyid(Repodata *data, Id handle, Id keyid, Id val, int overwrite break; if (*pp) { - if (overwrite) + if (overwrite || data->keys[*pp].type == REPOKEY_TYPE_DELETED) { pp[0] = keyid; pp[1] = val; @@ -1857,7 +1935,7 @@ repodata_set_poolstr(Repodata *data, Id solvid, Id keyname, const char *str) if (data->localpool) id = stringpool_str2id(&data->spool, str, 1); else - id = str2id(data->repo->pool, str, 1); + id = pool_str2id(data->repo->pool, str, 1); key.name = keyname; key.type = REPOKEY_TYPE_ID; key.size = 0; @@ -1915,8 +1993,37 @@ repodata_set_str(Repodata *data, Id solvid, Id keyname, const char *str) data->attrdatalen += l; } +void +repodata_set_binary(Repodata *data, Id solvid, Id keyname, void *buf, int len) +{ + Repokey key; + unsigned char *dp; + + key.name = keyname; + key.type = REPOKEY_TYPE_BINARY; + key.size = 0; + key.storage = KEY_STORAGE_INCORE; + data->attrdata = sat_extend(data->attrdata, data->attrdatalen, len + 5, 1, REPODATA_ATTRDATA_BLOCK); + dp = data->attrdata + data->attrdatalen; + if (len >= (1 << 14)) + { + if (len >= (1 << 28)) + *dp++ = (len >> 28) | 128; + if (len >= (1 << 21)) + *dp++ = (len >> 21) | 128; + *dp++ = (len >> 14) | 128; + } + if (len >= (1 << 7)) + *dp++ = (len >> 7) | 128; + *dp++ = len & 127; + if (len) + memcpy(dp, buf, len); + repodata_set(data, solvid, &key, data->attrdatalen); + data->attrdatalen = dp + len - data->attrdata; +} + /* add an array element consisting of entrysize Ids to the repodata. modifies attriddata - * so that the caller can append the new element there */ + * so that the caller can append entrysize new elements plus the termination zero there */ static void repodata_add_array(Repodata *data, Id handle, Id keyname, Id keytype, int entrysize) { @@ -1936,20 +2043,26 @@ repodata_add_array(Repodata *data, Id handle, Id keyname, Id keytype, int entrys ppp = repodata_get_attrp(data, handle); pp = *ppp; if (pp) - for (; *pp; pp += 2) - if (data->keys[*pp].name == keyname && data->keys[*pp].type == keytype) - break; - if (!pp || !*pp) + { + for (; *pp; pp += 2) + if (data->keys[*pp].name == keyname) + break; + } + if (!pp || !*pp || data->keys[*pp].type != keytype) { /* not found. allocate new key */ Repokey key; + Id keyid; key.name = keyname; key.type = keytype; key.size = 0; key.storage = KEY_STORAGE_INCORE; data->attriddata = sat_extend(data->attriddata, data->attriddatalen, entrysize + 1, sizeof(Id), REPODATA_ATTRIDDATA_BLOCK); - repodata_set(data, handle, &key, data->attriddatalen); - data->lasthandle = 0; /* next time... */ + keyid = repodata_key2id(data, &key, 1); + repodata_insert_keyid(data, handle, keyid, data->attriddatalen, 1); + data->lasthandle = handle; + data->lastkey = keyid; + data->lastdatalen = data->attriddatalen + entrysize + 1; return; } oldsize = 0; @@ -1993,31 +2106,6 @@ repodata_set_bin_checksum(Repodata *data, Id solvid, Id keyname, Id type, data->attrdatalen += l; } -static int -hexstr2bytes(unsigned char *buf, const char *str, int buflen) -{ - int i; - for (i = 0; i < buflen; i++) - { -#define c2h(c) (((c)>='0' && (c)<='9') ? ((c)-'0') \ - : ((c)>='a' && (c)<='f') ? ((c)-('a'-10)) \ - : ((c)>='A' && (c)<='F') ? ((c)-('A'-10)) \ - : -1) - int v = c2h(*str); - str++; - if (v < 0) - return 0; - buf[i] = v; - v = c2h(*str); - str++; - if (v < 0) - return 0; - buf[i] = (buf[i] << 4) | v; -#undef c2h - } - return buflen; -} - void repodata_set_checksum(Repodata *data, Id solvid, Id keyname, Id type, const char *str) @@ -2027,7 +2115,7 @@ repodata_set_checksum(Repodata *data, Id solvid, Id keyname, Id type, if (!(l = sat_chksum_len(type))) return; - if (hexstr2bytes(buf, str, l) != l) + if (l > sizeof(buf) || sat_hex2bin(&str, buf, l) != l) return; repodata_set_bin_checksum(data, solvid, keyname, type, buf); } @@ -2035,29 +2123,18 @@ repodata_set_checksum(Repodata *data, Id solvid, Id keyname, Id type, const char * repodata_chk2str(Repodata *data, Id type, const unsigned char *buf) { - int i, l; - char *str, *s; + int l; if (!(l = sat_chksum_len(type))) return ""; - s = str = pool_alloctmpspace(data->repo->pool, 2 * l + 1); - for (i = 0; i < l; i++) - { - unsigned char v = buf[i]; - unsigned char w = v >> 4; - *s++ = w >= 10 ? w + ('a' - 10) : w + '0'; - w = v & 15; - *s++ = w >= 10 ? w + ('a' - 10) : w + '0'; - } - *s = 0; - return str; + return pool_bin2hex(data->repo->pool, buf, l); } /* rpm filenames don't contain the epoch, so strip it */ static inline const char * evrid2vrstr(Pool *pool, Id evrid) { - const char *p, *evr = id2str(pool, evrid); + const char *p, *evr = pool_id2str(pool, evrid); if (!evr) return evr; for (p = evr; *p >= '0' && *p <= '9'; p++) @@ -2098,7 +2175,7 @@ repodata_set_location(Repodata *data, Id solvid, int medianr, const char *dir, c s = pool->solvables + solvid; if (dir && l) { - str = id2str(pool, s->arch); + str = pool_id2str(pool, s->arch); if (!strncmp(dir, str, l) && !str[l]) repodata_set_void(data, solvid, SOLVABLE_MEDIADIR); else if (!dir[l]) @@ -2112,7 +2189,7 @@ repodata_set_location(Repodata *data, Id solvid, int medianr, const char *dir, c } } fp = file; - str = id2str(pool, s->name); + str = pool_id2str(pool, s->name); l = strlen(str); if ((!l || !strncmp(fp, str, l)) && fp[l] == '-') { @@ -2122,7 +2199,7 @@ repodata_set_location(Repodata *data, Id solvid, int medianr, const char *dir, c if ((!l || !strncmp(fp, str, l)) && fp[l] == '.') { fp += l + 1; - str = id2str(pool, s->arch); + str = pool_id2str(pool, s->arch); l = strlen(str); if ((!l || !strncmp(fp, str, l)) && !strcmp(fp + l, ".rpm")) { @@ -2135,6 +2212,23 @@ repodata_set_location(Repodata *data, Id solvid, int medianr, const char *dir, c } void +repodata_set_idarray(Repodata *data, Id solvid, Id keyname, Queue *q) +{ + Repokey key; + int i; + + key.name = keyname; + key.type = REPOKEY_TYPE_IDARRAY; + key.size = 0; + key.storage = KEY_STORAGE_INCORE; + repodata_set(data, solvid, &key, data->attriddatalen); + data->attriddata = sat_extend(data->attriddata, data->attriddatalen, q->count + 1, sizeof(Id), REPODATA_ATTRIDDATA_BLOCK); + for (i = 0; i < q->count; i++) + data->attriddata[data->attriddatalen++] = q->elements[i]; + data->attriddata[data->attriddatalen++] = 0; +} + +void repodata_add_dirnumnum(Repodata *data, Id solvid, Id keyname, Id dir, Id num, Id num2) { assert(dir); @@ -2189,7 +2283,7 @@ repodata_add_poolstr_array(Repodata *data, Id solvid, Id keyname, if (data->localpool) id = stringpool_str2id(&data->spool, str, 1); else - id = str2id(data->repo->pool, str, 1); + id = pool_str2id(data->repo->pool, str, 1); repodata_add_idarray(data, solvid, keyname, id); } @@ -2209,7 +2303,44 @@ repodata_add_flexarray(Repodata *data, Id solvid, Id keyname, Id ghandle) data->attriddata[data->attriddatalen++] = 0; } -/* add all attrs from src to dest */ +void +repodata_delete_uninternalized(Repodata *data, Id solvid, Id keyname) +{ + Id *pp, *ap, **app; + app = repodata_get_attrp(data, solvid); + ap = *app; + if (!ap) + return; + for (; *ap; ap += 2) + if (data->keys[*ap].name == keyname) + break; + if (!*ap) + return; + pp = ap; + ap += 2; + for (; *ap; ap += 2) + { + if (data->keys[*ap].name == keyname) + continue; + *pp++ = ap[0]; + *pp++ = ap[1]; + } + *pp = 0; +} + +/* XXX: does not work correctly, needs fix in iterators! */ +void +repodata_delete(Repodata *data, Id solvid, Id keyname) +{ + Repokey key; + key.name = keyname; + key.type = REPOKEY_TYPE_DELETED; + key.size = 0; + key.storage = KEY_STORAGE_INCORE; + repodata_set(data, solvid, &key, 0); +} + +/* add all (uninternalized) attrs from src to dest */ void repodata_merge_attrs(Repodata *data, Id dest, Id src) { @@ -2220,6 +2351,7 @@ repodata_merge_attrs(Repodata *data, Id dest, Id src) repodata_insert_keyid(data, dest, keyp[0], keyp[1], 0); } +/* add some (uninternalized) attrs from src to dest */ void repodata_merge_some_attrs(Repodata *data, Id dest, Id src, Map *keyidmap, int overwrite) { @@ -2235,7 +2367,7 @@ repodata_merge_some_attrs(Repodata *data, Id dest, Id src, Map *keyidmap, int ov /**********************************************************************/ -/* TODO: unify with repo_write! */ +/* TODO: unify with repo_write and repo_solv! */ #define EXTDATA_BLOCK 1023 @@ -2248,6 +2380,7 @@ static void data_addid(struct extdata *xd, Id x) { unsigned char *dp; + xd->buf = sat_extend(xd->buf, xd->len, 5, 1, EXTDATA_BLOCK); dp = xd->buf + xd->len; @@ -2270,7 +2403,7 @@ data_addideof(struct extdata *xd, Id x, int eof) { if (x >= 64) x = (x & 63) | ((x & ~63) << 1); - data_addid(xd, (eof ? x: x | 64)); + data_addid(xd, (eof ? x : x | 64)); } static void @@ -2283,14 +2416,14 @@ data_addblob(struct extdata *xd, unsigned char *blob, int len) /*********************************/ +/* internalalize some key into incore/vincore data */ + static void repodata_serialize_key(Repodata *data, struct extdata *newincore, struct extdata *newvincore, Id *schema, Repokey *key, Id val) { - /* Otherwise we have a new value. Parse it into the internal - form. */ Id *ida; struct extdata *xd; unsigned int oldvincorelen = 0; @@ -2325,6 +2458,14 @@ repodata_serialize_key(Repodata *data, struct extdata *newincore, case REPOKEY_TYPE_DIR: data_addid(xd, val); break; + case REPOKEY_TYPE_BINARY: + { + Id len; + unsigned char *dp = data_read_id(data->attrdata + val, &len); + dp += len; + data_addblob(xd, data->attrdata + val, dp - (data->attrdata + val)); + } + break; case REPOKEY_TYPE_IDARRAY: for (ida = data->attriddata + val; *ida; ida++) data_addideof(xd, ida[0], ida[1] ? 0 : 1); @@ -2350,21 +2491,13 @@ repodata_serialize_key(Repodata *data, struct extdata *newincore, schemaid = 0; for (ida = data->attriddata + val; *ida; ida++) { -#if 0 - fprintf(stderr, "serialize struct %d\n", *ida); -#endif sp = schema; Id *kp = data->xattrs[-*ida]; if (!kp) continue; num++; for (;*kp; kp += 2) - { -#if 0 - fprintf(stderr, " %s:%d\n", id2str(data->repo->pool, data->keys[*kp].name), kp[1]); -#endif - *sp++ = *kp; - } + *sp++ = *kp; *sp = 0; if (!schemaid) schemaid = repodata_schema2id(data, schema, 1); @@ -2373,9 +2506,6 @@ repodata_serialize_key(Repodata *data, struct extdata *newincore, pool_debug(data->repo->pool, SAT_FATAL, "fixarray substructs with different schemas\n"); exit(1); } -#if 0 - fprintf(stderr, " schema %d\n", schemaid); -#endif } if (!num) break; @@ -2387,10 +2517,7 @@ repodata_serialize_key(Repodata *data, struct extdata *newincore, if (!kp) continue; for (;*kp; kp += 2) - { - repodata_serialize_key(data, newincore, newvincore, - schema, data->keys + *kp, kp[1]); - } + repodata_serialize_key(data, newincore, newvincore, schema, data->keys + *kp, kp[1]); } break; } @@ -2416,10 +2543,7 @@ repodata_serialize_key(Repodata *data, struct extdata *newincore, data_addid(xd, schemaid); kp = data->xattrs[-*ida]; for (;*kp; kp += 2) - { - repodata_serialize_key(data, newincore, newvincore, - schema, data->keys + *kp, kp[1]); - } + repodata_serialize_key(data, newincore, newvincore, schema, data->keys + *kp, kp[1]); } break; } @@ -2576,7 +2700,7 @@ fprintf(stderr, "schemadata %p\n", data->schemadata); } key = data->keys + *keyp; #if 0 - fprintf(stderr, "internalize %d(%d):%s:%s\n", entry, entry + data->start, id2str(data->repo->pool, key->name), id2str(data->repo->pool, key->type)); + fprintf(stderr, "internalize %d(%d):%s:%s\n", entry, entry + data->start, pool_id2str(data->repo->pool, key->name), pool_id2str(data->repo->pool, key->type)); #endif ndp = dp; if (oldcount) @@ -2654,7 +2778,8 @@ repodata_load_stub(Repodata *data) { Repo *repo = data->repo; Pool *pool = repo->pool; - int r; + int r, i; + struct _Pool_tmpspace oldtmpspace; if (!pool->loadcallback) { @@ -2662,9 +2787,19 @@ repodata_load_stub(Repodata *data) return; } data->state = REPODATA_LOADING; + + /* save tmp space */ + oldtmpspace = pool->tmpspace; + memset(&pool->tmpspace, 0, sizeof(pool->tmpspace)); + r = pool->loadcallback(pool, data, pool->loadcallbackdata); - if (!r) - data->state = REPODATA_ERROR; + + /* restore tmp space */ + for (i = 0; i < POOL_TMPSPACEBUF; i++) + sat_free(pool->tmpspace.buf[i]); + pool->tmpspace = oldtmpspace; + + data->state = r ? REPODATA_AVAILABLE : REPODATA_ERROR; } void @@ -2677,10 +2812,19 @@ repodata_create_stubs(Repodata *data) Dataiterator di; Id xkeyname = 0; int i, cnt = 0; + int repodataid; + int datastart, dataend; + repodataid = data - repo->repodata; + datastart = data->start; + dataend = data->end; dataiterator_init(&di, pool, repo, SOLVID_META, REPOSITORY_EXTERNAL, 0, 0); while (dataiterator_step(&di)) - cnt++; + { + if (di.data - repo->repodata != repodataid) + continue; + cnt++; + } dataiterator_free(&di); if (!cnt) return; @@ -2688,11 +2832,8 @@ repodata_create_stubs(Repodata *data) for (i = 0; i < cnt; i++) { sdata = repo_add_repodata(repo, 0); - if (data->end > data->start) - { - repodata_extend(sdata, data->start); - repodata_extend(sdata, data->end - 1); - } + if (dataend > datastart) + repodata_extend_block(sdata, datastart, dataend - datastart); stubdataids[i] = sdata - repo->repodata; sdata->state = REPODATA_STUB; sdata->loadcallback = repodata_load_stub; @@ -2702,6 +2843,8 @@ repodata_create_stubs(Repodata *data) sdata = 0; while (dataiterator_step(&di)) { + if (di.data - repo->repodata != repodataid) + continue; if (di.key->name == REPOSITORY_EXTERNAL && !di.nparents) { dataiterator_entersub(&di); @@ -2729,7 +2872,7 @@ repodata_create_stubs(Repodata *data) case REPOKEY_TYPE_MD5: case REPOKEY_TYPE_SHA1: case REPOKEY_TYPE_SHA256: - repodata_set_checksum(sdata, SOLVID_META, di.key->name, di.key->type, di.kv.str); + repodata_set_bin_checksum(sdata, SOLVID_META, di.key->name, di.key->type, (const unsigned char *)di.kv.str); break; case REPOKEY_TYPE_IDARRAY: repodata_add_idarray(sdata, SOLVID_META, di.key->name, di.kv.id); @@ -2750,6 +2893,8 @@ repodata_create_stubs(Repodata *data) repodata_key2id(sdata, &xkey, 1); xkeyname = 0; } + default: + break; } } dataiterator_free(&di);