Skip to content

Commit 00ada46

Browse files
committed
Generalize uninternalized lookups
We now have the generic repodata_lookup_kv_uninternalized and repodata_search_uninternalized to access uninternalized data. Drop the old interface, the functions were only used in some metadata parsers. So it's an API change but nobody should notice.
1 parent 2cdefc1 commit 00ada46

6 files changed

Lines changed: 145 additions & 94 deletions

File tree

ext/repo_appdata.c

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -467,13 +467,40 @@ repo_add_appdata(Repo *repo, FILE *fp, int flags)
467467
return repo_add_appdata_fn(repo, fp, flags, 0, 0);
468468
}
469469

470+
struct uninternalized_filelist_data {
471+
Id did;
472+
Queue *res;
473+
};
474+
475+
static int
476+
search_uninternalized_filelist_cb(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv)
477+
{
478+
struct uninternalized_filelist_data *uf = cbdata;
479+
const char *str;
480+
Id id;
481+
size_t l;
482+
if (key->type != REPOKEY_TYPE_DIRSTRARRAY || kv->id != uf->did)
483+
return 0;
484+
str = kv->str;
485+
l = strlen(str);
486+
if (l > 12 && strncmp(str + l - 12, ".appdata.xml", 12))
487+
id = pool_str2id(data->repo->pool, str, 1);
488+
else if (l > 13 && strncmp(str + l - 13, ".metainfo.xml", 13))
489+
id = pool_str2id(data->repo->pool, str, 1);
490+
else
491+
return 0;
492+
queue_push2(uf->res, s - data->repo->pool->solvables, id);
493+
return 0;
494+
}
495+
470496
static void
471497
search_uninternalized_filelist(Repo *repo, const char *dir, Queue *res)
472498
{
473499
Pool *pool = repo->pool;
474-
Id rdid, p;
475-
Id iter, did, idid;
500+
Id did, rdid, p;
501+
struct uninternalized_filelist_data uf;
476502

503+
uf.res = res;
477504
for (rdid = 1; rdid < repo->nrepodata; rdid++)
478505
{
479506
Repodata *data = repo_id2repodata(repo, rdid);
@@ -486,31 +513,12 @@ search_uninternalized_filelist(Repo *repo, const char *dir, Queue *res)
486513
did = repodata_str2dir(data, dir, 0);
487514
if (!did)
488515
continue;
516+
uf.did = did;
489517
for (p = data->start; p < data->end; p++)
490518
{
491-
if (p >= pool->nsolvables)
519+
if (p >= pool->nsolvables || pool->solvables[p].repo != repo)
492520
continue;
493-
if (pool->solvables[p].repo != repo)
494-
continue;
495-
iter = 0;
496-
for (;;)
497-
{
498-
const char *str;
499-
int l;
500-
Id id;
501-
idid = did;
502-
str = repodata_lookup_dirstrarray_uninternalized(data, p, SOLVABLE_FILELIST, &idid, &iter);
503-
if (!iter)
504-
break;
505-
l = strlen(str);
506-
if (l > 12 && strncmp(str + l - 12, ".appdata.xml", 12))
507-
id = pool_str2id(pool, str, 1);
508-
else if (l > 13 && strncmp(str + l - 13, ".metainfo.xml", 13))
509-
id = pool_str2id(pool, str, 1);
510-
else
511-
continue;
512-
queue_push2(res, p, id);
513-
}
521+
repodata_search_uninternalized(data, p, SOLVABLE_FILELIST, 0, search_uninternalized_filelist_cb, &uf);
514522
}
515523
}
516524
}

ext/repo_rpmmd.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -603,17 +603,18 @@ static void
603603
fill_cshash_from_new_solvables(struct parsedata *pd)
604604
{
605605
Pool *pool = pd->pool;
606-
Id cstype = 0;
607-
unsigned const char *cs;
608-
int i;
606+
int i, l;
607+
KeyValue kv;
608+
Repokey *key;
609609

610610
for (i = pd->first; i < pool->nsolvables; i++)
611611
{
612612
if (pool->solvables[i].repo != pd->repo)
613613
continue;
614-
cs = repodata_lookup_bin_checksum_uninternalized(pd->data, i, SOLVABLE_CHECKSUM, &cstype);
615-
if (cs)
616-
put_in_cshash(pd, cs, solv_chksum_len(cstype), i);
614+
if ((key = repodata_lookup_kv_uninternalized(pd->data, i, SOLVABLE_CHECKSUM, &kv)) == 0)
615+
continue;
616+
if ((l = solv_chksum_len(key->type)) != 0)
617+
put_in_cshash(pd, (const unsigned char *)kv.str, l, i);
617618
}
618619
}
619620

ext/repo_susetags.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,16 @@ lookup_shared_id(Repodata *data, Id p, Id keyname, Id voidid, int uninternalized
333333
return r;
334334
}
335335
if (uninternalized)
336-
return repodata_lookup_id_uninternalized(data, p, keyname, voidid);
336+
{
337+
KeyValue kv;
338+
Repokey *key = repodata_lookup_kv_uninternalized(data, p, keyname, &kv);
339+
if (!key)
340+
return 0;
341+
if (key->type == REPOKEY_TYPE_VOID)
342+
return voidid;
343+
if (key->type == REPOKEY_TYPE_ID)
344+
return kv.id;
345+
}
337346
return 0;
338347
}
339348

src/libsolv.ver

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -202,12 +202,10 @@ SOLV_1.0 {
202202
repodata_key2id;
203203
repodata_localize_id;
204204
repodata_lookup_bin_checksum;
205-
repodata_lookup_bin_checksum_uninternalized;
206205
repodata_lookup_binary;
207-
repodata_lookup_dirstrarray_uninternalized;
208206
repodata_lookup_id;
209-
repodata_lookup_id_uninternalized;
210207
repodata_lookup_idarray;
208+
repodata_lookup_kv_uninternalized;
211209
repodata_lookup_num;
212210
repodata_lookup_str;
213211
repodata_lookup_type;
@@ -220,6 +218,7 @@ SOLV_1.0 {
220218
repodata_search;
221219
repodata_search_arrayelement;
222220
repodata_search_keyskip;
221+
repodata_search_uninternalized;
223222
repodata_set_binary;
224223
repodata_set_bin_checksum;
225224
repodata_set_checksum;

src/repodata.c

Lines changed: 91 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -933,86 +933,121 @@ repodata_translate_dir_slow(Repodata *data, Repodata *fromdata, Id dir, int crea
933933
return compid;
934934
}
935935

936-
/* uninternalized lookups */
936+
/************************************************************************
937+
* uninternalized lookup / search
938+
*/
937939

938-
Id
939-
repodata_lookup_id_uninternalized(Repodata *data, Id solvid, Id keyname, Id voidid)
940+
static void
941+
data_fetch_uninternalized(Repodata *data, Repokey *key, Id value, KeyValue *kv)
942+
{
943+
Id *array;
944+
kv->eof = 1;
945+
switch (key->type)
946+
{
947+
case REPOKEY_TYPE_STR:
948+
kv->str = (const char *)data->attrdata + value;
949+
return;
950+
case REPOKEY_TYPE_CONSTANT:
951+
kv->num2 = 0;
952+
kv->num = key->size;
953+
return;
954+
case REPOKEY_TYPE_CONSTANTID:
955+
kv->id = key->size;
956+
return;
957+
case REPOKEY_TYPE_NUM:
958+
kv->num2 = 0;
959+
kv->num = value;
960+
if (value & 0x80000000)
961+
{
962+
kv->num = (unsigned int)data->attrnum64data[value ^ 0x80000000];
963+
kv->num2 = (unsigned int)(data->attrnum64data[value ^ 0x80000000] >> 32);
964+
}
965+
return;
966+
case_CHKSUM_TYPES:
967+
kv->num = 0; /* not stringified */
968+
kv->str = (const char *)data->attrdata + value;
969+
return;
970+
case REPOKEY_TYPE_IDARRAY:
971+
array = data->attriddata + (value + kv->entry);
972+
kv->id = array[0];
973+
kv->eof = array[1] ? 0 : 1;
974+
return;
975+
case REPOKEY_TYPE_DIRSTRARRAY:
976+
kv->num = 0; /* not stringified */
977+
array = data->attriddata + (value + kv->entry * 2);
978+
kv->id = array[0];
979+
kv->str = (const char *)data->attrdata + array[1];
980+
kv->eof = array[2] ? 0 : 1;
981+
return;
982+
case REPOKEY_TYPE_DIRNUMNUMARRAY:
983+
array = data->attriddata + (value + kv->entry * 3);
984+
kv->id = array[0];
985+
kv->num = array[1];
986+
kv->num2 = array[2];
987+
kv->eof = array[3] ? 0 : 1;
988+
return;
989+
case REPOKEY_TYPE_FIXARRAY:
990+
case REPOKEY_TYPE_FLEXARRAY:
991+
array = data->attriddata + (value + kv->entry);
992+
kv->id = array[0]; /* the handle */
993+
kv->eof = array[1] ? 0 : 1;
994+
return;
995+
default:
996+
kv->id = value;
997+
return;
998+
}
999+
}
1000+
1001+
Repokey *
1002+
repodata_lookup_kv_uninternalized(Repodata *data, Id solvid, Id keyname, KeyValue *kv)
9401003
{
9411004
Id *ap;
942-
if (!data->attrs)
1005+
if (!data->attrs || solvid < data->start || solvid >= data->end)
9431006
return 0;
9441007
ap = data->attrs[solvid - data->start];
9451008
if (!ap)
9461009
return 0;
9471010
for (; *ap; ap += 2)
9481011
{
949-
if (data->keys[*ap].name != keyname)
1012+
Repokey *key = data->keys + *ap;
1013+
if (key->name != keyname)
9501014
continue;
951-
if (data->keys[*ap].type == REPOKEY_TYPE_VOID)
952-
return voidid;
953-
if (data->keys[*ap].type == REPOKEY_TYPE_ID)
954-
return ap[1];
955-
return 0;
1015+
data_fetch_uninternalized(data, key, ap[1], kv);
1016+
return key;
9561017
}
9571018
return 0;
9581019
}
9591020

960-
/* returns the basename, stores the dir id in didp */
961-
const char *
962-
repodata_lookup_dirstrarray_uninternalized(Repodata *data, Id solvid, Id keyname, Id *didp, Id *iterp)
963-
{
964-
Id *ap, did;
965-
Id iter = *iterp;
966-
if (iter == 0) /* find key data */
967-
{
968-
if (!data->attrs)
969-
return 0;
970-
ap = data->attrs[solvid - data->start];
971-
if (!ap)
972-
return 0;
973-
for (; *ap; ap += 2)
974-
if (data->keys[*ap].name == keyname && data->keys[*ap].type == REPOKEY_TYPE_DIRSTRARRAY)
975-
break;
976-
if (!*ap)
977-
return 0;
978-
iter = ap[1];
979-
}
980-
did = *didp;
981-
for (ap = data->attriddata + iter; *ap; ap += 2)
982-
{
983-
if (did && ap[0] != did)
984-
continue;
985-
*didp = ap[0];
986-
*iterp = ap - data->attriddata + 2;
987-
return (const char *)data->attrdata + ap[1];
988-
}
989-
*iterp = 0;
990-
return 0;
991-
}
992-
993-
const unsigned char *
994-
repodata_lookup_bin_checksum_uninternalized(Repodata *data, Id solvid, Id keyname, Id *typep)
1021+
void
1022+
repodata_search_uninternalized(Repodata *data, Id solvid, Id keyname, int flags, int (*callback)(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv), void *cbdata)
9951023
{
9961024
Id *ap;
997-
if (!data->attrs)
998-
return 0;
1025+
int stop;
1026+
Solvable *s;
1027+
KeyValue kv;
1028+
1029+
if (!data->attrs || solvid < data->start || solvid >= data->end)
1030+
return;
9991031
ap = data->attrs[solvid - data->start];
10001032
if (!ap)
1001-
return 0;
1033+
return;
10021034
for (; *ap; ap += 2)
10031035
{
1004-
if (data->keys[*ap].name != keyname)
1036+
Repokey *key = data->keys + *ap;
1037+
if (keyname && key->name != keyname)
10051038
continue;
1006-
switch (data->keys[*ap].type)
1039+
s = solvid > 0 ? data->repo->pool->solvables + solvid : 0;
1040+
kv.entry = 0;
1041+
do
10071042
{
1008-
case_CHKSUM_TYPES:
1009-
*typep = data->keys[*ap].type;
1010-
return (const unsigned char *)data->attrdata + ap[1];
1011-
default:
1012-
break;
1043+
data_fetch_uninternalized(data, key, ap[1], &kv);
1044+
stop = callback(cbdata, s, data, key, &kv);
1045+
kv.entry++;
10131046
}
1047+
while (!kv.eof && !stop);
1048+
if (keyname || stop > SEARCH_NEXT_KEY)
1049+
return;
10141050
}
1015-
return 0;
10161051
}
10171052

10181053
/************************************************************************

src/repodata.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -324,10 +324,9 @@ void repodata_set_location(Repodata *data, Id solvid, int medianr, const char *d
324324
void repodata_set_deltalocation(Repodata *data, Id handle, int medianr, const char *dir, const char *file);
325325
void repodata_set_sourcepkg(Repodata *data, Id solvid, const char *sourcepkg);
326326

327-
/* uninternalized data lookup */
328-
Id repodata_lookup_id_uninternalized(Repodata *data, Id solvid, Id keyname, Id voidid);
329-
const char *repodata_lookup_dirstrarray_uninternalized(Repodata *data, Id solvid, Id keyname, Id *didp, Id *iterp);
330-
const unsigned char *repodata_lookup_bin_checksum_uninternalized(Repodata *data, Id solvid, Id keyname, Id *typep);
327+
/* uninternalized data lookup / search */
328+
Repokey *repodata_lookup_kv_uninternalized(Repodata *data, Id solvid, Id keyname, struct _KeyValue *kv);
329+
void repodata_search_uninternalized(Repodata *data, Id solvid, Id keyname, int flags, int (*callback)(void *cbdata, Solvable *s, Repodata *data, Repokey *key, struct _KeyValue *kv), void *cbdata);
331330

332331
/* stats */
333332
unsigned int repodata_memused(Repodata *data);

0 commit comments

Comments
 (0)