Author: matz Date: Sun Apr 27 20:15:46 2008 New Revision: 9846 URL: http://svn.opensuse.org/viewcvs/zypp?rev=9846&view=rev Log: (De-)Serialize structured types. Dataiterator and repo_search support them too, but not yet nested, so that is unsupported for now. Modified: trunk/sat-solver/src/repo.h trunk/sat-solver/src/repo_solv.c trunk/sat-solver/src/repodata.c trunk/sat-solver/src/repopack.h trunk/sat-solver/tools/dumpsolv.c trunk/sat-solver/tools/repo_susetags.c trunk/sat-solver/tools/repo_write.c Modified: trunk/sat-solver/src/repo.h URL: http://svn.opensuse.org/viewcvs/zypp/trunk/sat-solver/src/repo.h?rev=9846&r1=9845&r2=9846&view=diff ============================================================================== --- trunk/sat-solver/src/repo.h (original) +++ trunk/sat-solver/src/repo.h Sun Apr 27 20:15:46 2008 @@ -189,6 +189,9 @@ KeyValue kv; regex_t regex; int regex_err; + Id *subkeyp; + int subnum; + Id subschema; } Dataiterator; /* Use these like: Modified: trunk/sat-solver/src/repo_solv.c URL: http://svn.opensuse.org/viewcvs/zypp/trunk/sat-solver/src/repo_solv.c?rev=9846&r1=9845&r2=9846&view=diff ============================================================================== --- trunk/sat-solver/src/repo_solv.c (original) +++ trunk/sat-solver/src/repo_solv.c Sun Apr 27 20:15:46 2008 @@ -710,7 +710,6 @@ // ---------------------------------------------- - /* * read repo from .solv file * and add it to pool @@ -1135,7 +1134,7 @@ type = idmap[type]; else if (parent) type = str2id(pool, stringpool_id2str(spool, type), 1); - if (type < REPOKEY_TYPE_VOID || type > REPOKEY_TYPE_SHA256) + if (type < REPOKEY_TYPE_VOID || type > REPOKEY_TYPE_COUNTED) { pool_debug(pool, SAT_ERROR, "unsupported data type '%s'\n", id2str(pool, type)); data.error = SOLV_ERROR_UNSUPPORTED; @@ -1455,9 +1454,40 @@ POOL_DEBUG(SAT_DEBUG_STATS," %s\n", dep2str(pool, repo->idarraydata[ido])); #endif break; + case REPOKEY_TYPE_COUNTED: + { + Id num, did; + dp = data_read_id(dp, &num); + incore_add_id(&data, num); + dp = data_read_id_max(dp, &did, 0, numschemata, &data.error); + incore_add_id(&data, did); + while (num--) + { + Id *kp = schemadata + schemata[did]; + for (; *kp; kp++) + { + Id tid; + switch (keys[*kp].type) + { + case REPOKEY_TYPE_ID: + dp = data_read_id_max(dp, &tid, idmap, numid + numrel, &data.error); + incore_add_id(&data, tid); + break; + default: + dps = dp; + //dp = data_skip(dp, keys[*kp].type); + dp = data_skip_recursive(&data, dp, keys + *kp); + incore_add_blob(&data, dps, dp - dps); + break; + } + } + } + } + break; default: dps = dp; - dp = data_skip(dp, keys[key].type); + //dp = data_skip(dp, keys[key].type); + dp = data_skip_recursive(&data, dp, keys + key); if (keys[key].storage == KEY_STORAGE_INCORE) incore_add_blob(&data, dps, dp - dps); break; Modified: trunk/sat-solver/src/repodata.c URL: http://svn.opensuse.org/viewcvs/zypp/trunk/sat-solver/src/repodata.c?rev=9846&r1=9845&r2=9846&view=diff ============================================================================== --- trunk/sat-solver/src/repodata.c (original) +++ trunk/sat-solver/src/repodata.c Sun Apr 27 20:15:46 2008 @@ -98,6 +98,24 @@ close(data->pagefd); } +unsigned char * +data_skip_recursive(Repodata *data, unsigned char *dp, Repokey *key) +{ + KeyValue kv; + if (key->type != REPOKEY_TYPE_COUNTED) + return data_skip(dp, key->type); + dp = data_fetch(dp, &kv, key); + int num = kv.num; + int schema = kv.id; + while (num--) + { + Id *keyp = data->schemadata + data->schemata[schema]; + for (; *keyp; keyp++) + dp = data_skip_recursive(data, dp, data->keys + *keyp); + } + return dp; +} + static unsigned char * forward_to_key(Repodata *data, Id keyid, Id schemaid, unsigned char *dp) { @@ -116,7 +134,7 @@ } if (data->keys[k].storage != KEY_STORAGE_INCORE) continue; - dp = data_skip(dp, data->keys[k].type); + dp = data_skip_recursive(data, dp, data->keys + k); } return 0; } @@ -317,7 +335,7 @@ if (key->storage == KEY_STORAGE_INCORE) { /* hmm, this is a bit expensive */ - *dpp = data_skip(dp, key->type); + *dpp = data_skip_recursive(data, dp, key); return dp; } else if (key->storage == KEY_STORAGE_VERTICAL_OFFSET) @@ -568,7 +586,32 @@ ddp = data_fetch(ddp, &kv, key); if (!ddp) break; - stop = callback(cbdata, data->repo->pool->solvables + data->start + entry, data, key, &kv); + if (key->type == REPOKEY_TYPE_COUNTED) + { + int num = kv.num; + int subschema = kv.id; + Repokey *countkey = key; + kv.eof = 0; + callback(cbdata, data->repo->pool->solvables + data->start + entry, data, countkey, &kv); + while (num--) + { + Id *kp = data->schemadata + data->schemata[subschema]; + for (; *kp; kp++) + { + key = data->keys + *kp; + ddp = data_fetch(ddp, &kv, key); + if (!ddp) + exit(1); + callback(cbdata, data->repo->pool->solvables + data->start + entry, data, key, &kv); + } + kv.eof = 1; + callback(cbdata, data->repo->pool->solvables + data->start + entry, data, countkey, &kv); + } + kv.eof = 2; + stop = callback(cbdata, data->repo->pool->solvables + data->start + entry, data, countkey, &kv); + } + else + stop = callback(cbdata, data->repo->pool->solvables + data->start + entry, data, key, &kv); } while (!kv.eof && !stop); if (onekey || stop > SEARCH_NEXT_KEY) @@ -702,6 +745,7 @@ di->kv.eof = 1; di->repo = repo; di->idp = 0; + di->subkeyp = 0; } /* FIXME factor and merge with repo_matchvalue */ @@ -908,6 +952,34 @@ continue; } } + else if (di->subkeyp) + { + Id keyid; + if (!di->subnum) + { + /* Send end-of-substruct. We are here only when we saw a + _COUNTED key one level up. Since then we didn't increment + ->keyp, so it still can be found at keyp[-1]. */ + di->kv.eof = 2; + di->key = di->data->keys + di->keyp[-1]; + di->subkeyp = 0; + } + else if (!(keyid = *di->subkeyp++)) + { + /* Send end-of-element. See above for keyp[-1]. */ + di->kv.eof = 1; + di->key = di->data->keys + di->keyp[-1]; + di->subkeyp = di->data->schemadata + di->data->schemata[di->subschema]; + di->subnum--; + } + else + { + di->key = di->data->keys + keyid; + di->dp = data_fetch(di->dp, &di->kv, di->key); + if (!di->dp) + exit(1); + } + } else { if (di->kv.eof) @@ -986,6 +1058,13 @@ } di->dp = data_fetch(di->dp, &di->kv, di->key); } + if (di->key->type == REPOKEY_TYPE_COUNTED) + { + di->subnum = di->kv.num; + di->subschema = di->kv.id; + di->kv.eof = 0; + di->subkeyp = di->data->schemadata + di->data->schemata[di->subschema]; + } } weg2: if (!di->match @@ -1523,7 +1602,9 @@ repodata_create_struct(Repodata *data, Id handle, Id keyname) { Id newhandle = get_new_struct(data); - repodata_add_idarray(data, handle, keyname, newhandle); + repodata_add_array(data, handle, keyname, REPOKEY_TYPE_COUNTED, 1); + data->attriddata[data->attriddatalen++] = newhandle; + data->attriddata[data->attriddatalen++] = 0; return newhandle; } @@ -1647,12 +1728,133 @@ return data->nschemata++; } +static void +repodata_serialize_key(Repodata *data, struct extdata *newincore, + struct extdata *newvincore, + Id *schema, Id *schematacache, + 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; + Id schemaid, *sp; + + xd = newincore; + if (key->storage == KEY_STORAGE_VERTICAL_OFFSET) + { + xd = newvincore; + oldvincorelen = xd->len; + } + switch (key->type) + { + case REPOKEY_TYPE_VOID: + case REPOKEY_TYPE_CONSTANT: + case REPOKEY_TYPE_CONSTANTID: + break; + case REPOKEY_TYPE_STR: + data_addblob(xd, data->attrdata + val, strlen((char *)(data->attrdata + val)) + 1); + break; + case REPOKEY_TYPE_MD5: + data_addblob(xd, data->attrdata + val, SIZEOF_MD5); + break; + case REPOKEY_TYPE_SHA1: + data_addblob(xd, data->attrdata + val, SIZEOF_SHA1); + break; + case REPOKEY_TYPE_ID: + case REPOKEY_TYPE_NUM: + case REPOKEY_TYPE_DIR: + data_addid(xd, val); + break; + case REPOKEY_TYPE_IDARRAY: + for (ida = data->attriddata + val; *ida; ida++) + data_addideof(xd, ida[0], ida[1] ? 0 : 1); + break; + case REPOKEY_TYPE_DIRNUMNUMARRAY: + for (ida = data->attriddata + val; *ida; ida += 3) + { + data_addid(xd, ida[0]); + data_addid(xd, ida[1]); + data_addideof(xd, ida[2], ida[3] ? 0 : 1); + } + break; + case REPOKEY_TYPE_DIRSTRARRAY: + for (ida = data->attriddata + val; *ida; ida += 2) + { + data_addideof(xd, ida[0], ida[2] ? 0 : 1); + data_addblob(xd, data->attrdata + ida[1], strlen((char *)(data->attrdata + ida[1])) + 1); + } + break; + case REPOKEY_TYPE_COUNTED: + { + int num = 0; + schemaid = 0; + for (ida = data->attriddata + val; *ida; ida++) + { +#if 0 + fprintf(stderr, "serialize struct %d\n", *ida); +#endif + sp = schema; + Id *kp = data->structs[*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 = 0; + if (!schemaid) + schemaid = addschema(data, schema, schematacache); + else if (schemaid != addschema(data, schema, schematacache)) + { + fprintf(stderr, " not yet implemented: substructs with different schemas\n"); + exit(1); + } +#if 0 + fprintf(stderr, " schema %d\n", schemaid); +#endif + } + if (!num) + break; + data_addid(xd, num); + data_addid(xd, schemaid); + for (ida = data->attriddata + val; *ida; ida++) + { + Id *kp = data->structs[*ida]; + if (!kp) + continue; + for (;*kp; kp += 2) + { + repodata_serialize_key(data, newincore, newvincore, + schema, schematacache, + data->keys + *kp, kp[1]); + } + } + break; + } + default: + fprintf(stderr, "don't know how to handle type %d\n", key->type); + exit(1); + } + if (key->storage == KEY_STORAGE_VERTICAL_OFFSET) + { + /* put offset/len in incore */ + data_addid(newincore, data->lastverticaloffset + oldvincorelen); + oldvincorelen = xd->len - oldvincorelen; + data_addid(newincore, oldvincorelen); + } +} void repodata_internalize(Repodata *data) { Repokey *key; - Id id, entry, nentry, *ida; + Id entry, nentry; Id schematacache[256]; Id schemaid, *schema, *sp, oldschema, *keyp, *seen; unsigned char *dp, *ndp; @@ -1745,6 +1947,9 @@ for (keyp = data->schemadata + data->schemata[schemaid]; *keyp; keyp++) { key = data->keys + *keyp; +#if 0 + fprintf(stderr, "internalize %d:%s:%s\n", entry, id2str(data->repo->pool, key->name), id2str(data->repo->pool, key->type)); +#endif ndp = dp; if (oldcount) { @@ -1755,7 +1960,7 @@ ndp = data_skip(ndp, REPOKEY_TYPE_ID); } else if (key->storage == KEY_STORAGE_INCORE) - ndp = data_skip(dp, key->type); + ndp = data_skip_recursive(data, dp, key); oldcount--; } if (seen[*keyp] == -1) @@ -1771,66 +1976,9 @@ { /* Otherwise we have a new value. Parse it into the internal form. */ - struct extdata *xd; - unsigned int oldvincorelen = 0; - - xd = &newincore; - if (key->storage == KEY_STORAGE_VERTICAL_OFFSET) - { - xd = &newvincore; - oldvincorelen = xd->len; - } - id = seen[*keyp] - 1; - switch (key->type) - { - case REPOKEY_TYPE_VOID: - case REPOKEY_TYPE_CONSTANT: - case REPOKEY_TYPE_CONSTANTID: - break; - case REPOKEY_TYPE_STR: - data_addblob(xd, data->attrdata + id, strlen((char *)(data->attrdata + id)) + 1); - break; - case REPOKEY_TYPE_MD5: - data_addblob(xd, data->attrdata + id, SIZEOF_MD5); - break; - case REPOKEY_TYPE_SHA1: - data_addblob(xd, data->attrdata + id, SIZEOF_SHA1); - break; - case REPOKEY_TYPE_ID: - case REPOKEY_TYPE_NUM: - case REPOKEY_TYPE_DIR: - data_addid(xd, id); - break; - case REPOKEY_TYPE_IDARRAY: - for (ida = data->attriddata + id; *ida; ida++) - data_addideof(xd, ida[0], ida[1] ? 0 : 1); - break; - case REPOKEY_TYPE_DIRNUMNUMARRAY: - for (ida = data->attriddata + id; *ida; ida += 3) - { - data_addid(xd, ida[0]); - data_addid(xd, ida[1]); - data_addideof(xd, ida[2], ida[3] ? 0 : 1); - } - break; - case REPOKEY_TYPE_DIRSTRARRAY: - for (ida = data->attriddata + id; *ida; ida += 2) - { - data_addideof(xd, ida[0], ida[2] ? 0 : 1); - data_addblob(xd, data->attrdata + ida[1], strlen((char *)(data->attrdata + ida[1])) + 1); - } - break; - default: - fprintf(stderr, "don't know how to handle type %d\n", key->type); - exit(1); - } - if (key->storage == KEY_STORAGE_VERTICAL_OFFSET) - { - /* put offset/len in incore */ - data_addid(&newincore, data->lastverticaloffset + oldvincorelen); - oldvincorelen = xd->len - oldvincorelen; - data_addid(&newincore, oldvincorelen); - } + repodata_serialize_key(data, &newincore, &newvincore, + schema, schematacache, + key, seen[*keyp] - 1); } dp = ndp; } Modified: trunk/sat-solver/src/repopack.h URL: http://svn.opensuse.org/viewcvs/zypp/trunk/sat-solver/src/repopack.h?rev=9846&r1=9845&r2=9846&view=diff ============================================================================== --- trunk/sat-solver/src/repopack.h (original) +++ trunk/sat-solver/src/repopack.h Sun Apr 27 20:15:46 2008 @@ -103,6 +103,9 @@ dp = data_read_id(dp, &kv->id); dp = data_read_id(dp, &kv->num); return data_read_ideof(dp, &kv->num2, &kv->eof); + case REPOKEY_TYPE_COUNTED: + dp = data_read_id(dp, &kv->num); + return data_read_id(dp, &kv->id); default: return 0; } @@ -168,6 +171,13 @@ return dp + 1; dp++; } + case REPOKEY_TYPE_COUNTED: + while ((*dp & 0x80) != 0) + dp++; + dp++; + while ((*dp & 0x80) != 0) + dp++; + return dp + 1; default: return 0; } @@ -247,9 +257,19 @@ return dp + 1; dp++; } + case REPOKEY_TYPE_COUNTED: + while ((*dp & 0x80) != 0) + dp++; + dp++; + while ((*dp & 0x80) != 0) + dp++; + return dp + 1; default: return 0; } } +unsigned char * data_skip_recursive(Repodata *data, unsigned char *dp, + Repokey *key); + #endif /* SATSOLVER_REPOPACK */ Modified: trunk/sat-solver/tools/dumpsolv.c URL: http://svn.opensuse.org/viewcvs/zypp/trunk/sat-solver/tools/dumpsolv.c?rev=9846&r1=9845&r2=9846&view=diff ============================================================================== --- trunk/sat-solver/tools/dumpsolv.c (original) +++ trunk/sat-solver/tools/dumpsolv.c Sun Apr 27 20:15:46 2008 @@ -103,6 +103,9 @@ case REPOKEY_TYPE_DIRSTRARRAY: printf("%s: %s\n", keyname, repodata_dir2str(data, kv->id, kv->str)); break; + case REPOKEY_TYPE_COUNTED: + printf("%s: %s\n", keyname, kv->eof == 0 ? "open" : kv->eof == 1 ? "next" : "close"); + break; default: printf("%s: ?\n", keyname); break; @@ -110,11 +113,11 @@ return 0; } -static int +/*static int dump_repoattrs_cb(void *vcbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv) { return dump_attr(s->repo, data, key, kv); -} +}*/ /* * dump all attributes for Id <p> @@ -123,7 +126,7 @@ void dump_repoattrs(Repo *repo, Id p) { -#if 1 +#if 0 repo_search(repo, p, 0, 0, SEARCH_NO_STORAGE_SOLVABLE, dump_repoattrs_cb, 0); #else Dataiterator di; Modified: trunk/sat-solver/tools/repo_susetags.c URL: http://svn.opensuse.org/viewcvs/zypp/trunk/sat-solver/tools/repo_susetags.c?rev=9846&r1=9845&r2=9846&view=diff ============================================================================== --- trunk/sat-solver/tools/repo_susetags.c (original) +++ trunk/sat-solver/tools/repo_susetags.c Sun Apr 27 20:15:46 2008 @@ -872,6 +872,15 @@ break; case CTAG('=', 'C', 'k', 's'): set_checksum(data, handle, SOLVABLE_CHECKSUM, line + 6); + if (0) + { + Id sub = repodata_create_struct(data, handle, str2id(pool, "solvable:komisch", 1)); + repodata_set_poolstr(data, sub, str2id(pool, "sub:key1", 1), line + 6); + repodata_set_num(data, sub, str2id(pool, "sub:key2", 1), last_found_pack); + sub = repodata_create_struct(data, handle, str2id(pool, "solvable:komisch", 1)); + repodata_set_poolstr(data, sub, str2id(pool, "sub:key1", 1), line + 7); + repodata_set_num(data, sub, str2id(pool, "sub:key2", 1), last_found_pack+1); + } break; case CTAG('=', 'L', 'a', 'n'): language = strdup(line + 6); Modified: trunk/sat-solver/tools/repo_write.c URL: http://svn.opensuse.org/viewcvs/zypp/trunk/sat-solver/tools/repo_write.c?rev=9846&r1=9845&r2=9846&view=diff ============================================================================== --- trunk/sat-solver/tools/repo_write.c (original) +++ trunk/sat-solver/tools/repo_write.c Sun Apr 27 20:15:46 2008 @@ -371,6 +371,7 @@ Id *schema; /* schema construction space */ Id *sp; /* pointer in above */ + Id *oldschema, *oldsp; Id *myschemata; int nmyschemata; @@ -382,6 +383,9 @@ Id *solvschemata; Id *extraschemata; + Id *subschemata; + int nsubschemata; + int current_sub; struct extdata *extdata; @@ -634,7 +638,8 @@ if (!rm) return SEARCH_NEXT_KEY; /* we do not want this one */ /* record key in schema */ - if (cbdata->sp == cbdata->schema || cbdata->sp[-1] != rm) + if ((key->type != REPOKEY_TYPE_COUNTED || kv->eof == 0) + && (cbdata->sp == cbdata->schema || cbdata->sp[-1] != rm)) *cbdata->sp++ = rm; switch(key->type) { @@ -654,6 +659,38 @@ else setdirused(cbdata, &data->dirpool, id); break; + case REPOKEY_TYPE_COUNTED: + if (kv->eof == 0) + { + if (cbdata->oldschema) + { + fprintf(stderr, "nested structs not yet implemented\n"); + exit(1); + } + cbdata->oldschema = cbdata->schema; + cbdata->oldsp = cbdata->sp; + cbdata->schema = sat_calloc(cbdata->nmykeys, sizeof(Id)); + cbdata->sp = cbdata->schema; + } + else if (kv->eof == 1) + { + cbdata->current_sub++; + *cbdata->sp = 0; + cbdata->subschemata = sat_extend(cbdata->subschemata, cbdata->nsubschemata, 1, sizeof(Id), SCHEMATA_BLOCK); + cbdata->subschemata[cbdata->nsubschemata++] = addschema(cbdata, cbdata->schema); +#if 0 + fprintf(stderr, "Have schema %d\n", cbdata->subschemata[cbdata->nsubschemata-1]); +#endif + cbdata->sp = cbdata->schema; + } + else + { + sat_free(cbdata->schema); + cbdata->schema = cbdata->oldschema; + cbdata->sp = cbdata->oldsp; + cbdata->oldsp = cbdata->oldschema = 0; + } + break; default: break; } @@ -756,6 +793,26 @@ data_addideof(xd, id, kv->eof); data_addblob(xd, (unsigned char *)kv->str, strlen(kv->str) + 1); break; + case REPOKEY_TYPE_COUNTED: + if (kv->eof == 0) + { + if (kv->num) + { + data_addid(xd, kv->num); + data_addid(xd, cbdata->subschemata[cbdata->current_sub]); +#if 0 + fprintf(stderr, "writing %d %d\n", kv->num, cbdata->subschemata[cbdata->current_sub]); +#endif + } + } + else if (kv->eof == 1) + { + cbdata->current_sub++; + } + else + { + } + break; default: fprintf(stderr, "unknown type for %d: %d\n", key->name, key->type); exit(1); @@ -1449,6 +1506,7 @@ /********************************************************************/ cbdata.extdata = sat_calloc(cbdata.nmykeys, sizeof(struct extdata)); + cbdata.current_sub = 0; xd = cbdata.extdata; maxentrysize = 0; for (i = repo->start, s = pool->solvables + i, n = 0; i < repo->end; i++, s++) -- To unsubscribe, e-mail: zypp-commit+unsubscribe@opensuse.org For additional commands, e-mail: zypp-commit+help@opensuse.org