Skip to content

Commit 6c9d385

Browse files
committed
Improve handling of relations in repo_write
The old way was way to complex. What was I thinking?
1 parent 0ce0471 commit 6c9d385

1 file changed

Lines changed: 101 additions & 52 deletions

File tree

src/repo_write.c

Lines changed: 101 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ typedef struct needid {
3838
} NeedId;
3939

4040

41-
#define RELOFF(id) (needid[0].map + GETRELID(id))
41+
#define NEEDIDOFF(id) (ISRELDEP(id) ? (needid[0].map + GETRELID(id)) : id)
4242

4343
/*
4444
* increment need Id
@@ -49,44 +49,22 @@ typedef struct needid {
4949
*
5050
*/
5151

52-
static void
53-
incneedid(Pool *pool, Id id, NeedId *needid)
52+
static inline void
53+
incneedid(Id id, NeedId *needid)
5454
{
55-
while (ISRELDEP(id))
56-
{
57-
Reldep *rd = GETRELDEP(pool, id);
58-
needid[RELOFF(id)].need++;
59-
if (ISRELDEP(rd->evr))
60-
incneedid(pool, rd->evr, needid);
61-
else
62-
needid[rd->evr].need++;
63-
id = rd->name;
64-
}
65-
needid[id].need++;
55+
needid[NEEDIDOFF(id)].need++;
6656
}
6757

6858
static int
69-
incneedidarray(Pool *pool, Id *idarray, NeedId *needid)
59+
incneedidarray(Id *idarray, NeedId *needid)
7060
{
7161
Id id;
7262
int n = 0;
7363

74-
if (!idarray)
75-
return 0;
7664
while ((id = *idarray++) != 0)
7765
{
7866
n++;
79-
while (ISRELDEP(id))
80-
{
81-
Reldep *rd = GETRELDEP(pool, id);
82-
needid[RELOFF(id)].need++;
83-
if (ISRELDEP(rd->evr))
84-
incneedid(pool, rd->evr, needid);
85-
else
86-
needid[rd->evr].need++;
87-
id = rd->name;
88-
}
89-
needid[id].need++;
67+
needid[NEEDIDOFF(id)].need++;
9068
}
9169
return n + 1;
9270
}
@@ -248,7 +226,7 @@ write_idarray(Repodata *data, Pool *pool, NeedId *needid, Id *ids)
248226
{
249227
id = *ids++;
250228
if (needid)
251-
id = needid[ISRELDEP(id) ? RELOFF(id) : id].need;
229+
id = needid[NEEDIDOFF(id)].need;
252230
if (id >= 64)
253231
id = (id & 63) | ((id & ~63) << 1);
254232
if (!*ids)
@@ -272,6 +250,7 @@ struct cbdata {
272250

273251
Stringpool *ownspool;
274252
Dirpool *owndirpool;
253+
int clonepool; /* are the pool ids cloned into ownspool? */
275254

276255
Id *keymap; /* keymap for this repodata */
277256

@@ -410,7 +389,7 @@ data_adddepids(struct extdata *xd, Pool *pool, NeedId *needid, Id *ids, Id marke
410389
{
411390
Id id = ids[len];
412391
if (needid)
413-
id = needid[ISRELDEP(id) ? RELOFF(id) : id].need;
392+
id = needid[NEEDIDOFF(id)].need;
414393
lids[len] = id;
415394
}
416395
if (ids[len])
@@ -423,7 +402,7 @@ data_adddepids(struct extdata *xd, Pool *pool, NeedId *needid, Id *ids, Id marke
423402
{
424403
Id id = ids[len];
425404
if (needid)
426-
id = needid[ISRELDEP(id) ? RELOFF(id) : id].need;
405+
id = needid[NEEDIDOFF(id)].need;
427406
sids[len] = id;
428407
}
429408
}
@@ -492,7 +471,7 @@ data_adddepids(struct extdata *xd, Pool *pool, NeedId *needid, Id *ids, Id marke
492471
while ((id = *ids++) != 0)
493472
{
494473
if (needid)
495-
id = needid[ISRELDEP(id) ? RELOFF(id) : id].need;
474+
id = needid[NEEDIDOFF(id)].need;
496475
data_addideof(xd, id, *ids ? 0 : 1);
497476
}
498477
}
@@ -552,7 +531,7 @@ putinowndirpool_slow(struct cbdata *cbdata, Repodata *data, Dirpool *dp, Id dir)
552531
if (parent)
553532
parent = putinowndirpool_slow(cbdata, data, dp, parent);
554533
compid = dirpool_compid(dp, dir);
555-
if (cbdata->ownspool && compid > 1)
534+
if (cbdata->ownspool && compid > 1 && (!cbdata->clonepool || data->localpool))
556535
compid = putinownpool(cbdata, data, compid);
557536
return dirpool_add_dir(cbdata->owndirpool, parent, compid, 1);
558537
}
@@ -622,9 +601,9 @@ collect_needed_cb(void *vcbdata, Solvable *s, Repodata *data, Repokey *key, KeyV
622601
case REPOKEY_TYPE_ID:
623602
case REPOKEY_TYPE_IDARRAY:
624603
id = kv->id;
625-
if (!ISRELDEP(id) && cbdata->ownspool && id > 1)
604+
if (!ISRELDEP(id) && cbdata->ownspool && id > 1 && (!cbdata->clonepool || data->localpool))
626605
id = putinownpool(cbdata, data, id);
627-
incneedid(cbdata->pool, id, cbdata->needid);
606+
incneedid(id, cbdata->needid);
628607
break;
629608
case REPOKEY_TYPE_DIR:
630609
case REPOKEY_TYPE_DIRNUMNUMARRAY:
@@ -668,7 +647,6 @@ collect_needed_solvable(struct cbdata *cbdata, Solvable *s, Id *keymap)
668647
{
669648
/* set schema info, keep in sync with collect_data_solvable */
670649
Repo *repo = s->repo;
671-
Pool *pool = repo->pool;
672650
Id *sp = cbdata->sp;
673651
NeedId *needid = cbdata->needid;
674652
Repodata *target = cbdata->target;
@@ -697,42 +675,42 @@ collect_needed_solvable(struct cbdata *cbdata, Solvable *s, Id *keymap)
697675
if (s->provides && keymap[SOLVABLE_PROVIDES])
698676
{
699677
*sp++ = keymap[SOLVABLE_PROVIDES];
700-
target->keys[keymap[SOLVABLE_PROVIDES]].size += incneedidarray(pool, idarraydata + s->provides, needid);
678+
target->keys[keymap[SOLVABLE_PROVIDES]].size += incneedidarray(idarraydata + s->provides, needid);
701679
}
702680
if (s->obsoletes && keymap[SOLVABLE_OBSOLETES])
703681
{
704682
*sp++ = keymap[SOLVABLE_OBSOLETES];
705-
target->keys[keymap[SOLVABLE_OBSOLETES]].size += incneedidarray(pool, idarraydata + s->obsoletes, needid);
683+
target->keys[keymap[SOLVABLE_OBSOLETES]].size += incneedidarray(idarraydata + s->obsoletes, needid);
706684
}
707685
if (s->conflicts && keymap[SOLVABLE_CONFLICTS])
708686
{
709687
*sp++ = keymap[SOLVABLE_CONFLICTS];
710-
target->keys[keymap[SOLVABLE_CONFLICTS]].size += incneedidarray(pool, idarraydata + s->conflicts, needid);
688+
target->keys[keymap[SOLVABLE_CONFLICTS]].size += incneedidarray(idarraydata + s->conflicts, needid);
711689
}
712690
if (s->requires && keymap[SOLVABLE_REQUIRES])
713691
{
714692
*sp++ = keymap[SOLVABLE_REQUIRES];
715-
target->keys[keymap[SOLVABLE_REQUIRES]].size += incneedidarray(pool, idarraydata + s->requires, needid);
693+
target->keys[keymap[SOLVABLE_REQUIRES]].size += incneedidarray(idarraydata + s->requires, needid);
716694
}
717695
if (s->recommends && keymap[SOLVABLE_RECOMMENDS])
718696
{
719697
*sp++ = keymap[SOLVABLE_RECOMMENDS];
720-
target->keys[keymap[SOLVABLE_RECOMMENDS]].size += incneedidarray(pool, idarraydata + s->recommends, needid);
698+
target->keys[keymap[SOLVABLE_RECOMMENDS]].size += incneedidarray(idarraydata + s->recommends, needid);
721699
}
722700
if (s->suggests && keymap[SOLVABLE_SUGGESTS])
723701
{
724702
*sp++ = keymap[SOLVABLE_SUGGESTS];
725-
target->keys[keymap[SOLVABLE_SUGGESTS]].size += incneedidarray(pool, idarraydata + s->suggests, needid);
703+
target->keys[keymap[SOLVABLE_SUGGESTS]].size += incneedidarray(idarraydata + s->suggests, needid);
726704
}
727705
if (s->supplements && keymap[SOLVABLE_SUPPLEMENTS])
728706
{
729707
*sp++ = keymap[SOLVABLE_SUPPLEMENTS];
730-
target->keys[keymap[SOLVABLE_SUPPLEMENTS]].size += incneedidarray(pool, idarraydata + s->supplements, needid);
708+
target->keys[keymap[SOLVABLE_SUPPLEMENTS]].size += incneedidarray(idarraydata + s->supplements, needid);
731709
}
732710
if (s->enhances && keymap[SOLVABLE_ENHANCES])
733711
{
734712
*sp++ = keymap[SOLVABLE_ENHANCES];
735-
target->keys[keymap[SOLVABLE_ENHANCES]].size += incneedidarray(pool, idarraydata + s->enhances, needid);
713+
target->keys[keymap[SOLVABLE_ENHANCES]].size += incneedidarray(idarraydata + s->enhances, needid);
736714
}
737715
if (repo->rpmdbid && keymap[RPM_RPMDBID])
738716
{
@@ -780,18 +758,18 @@ collect_data_cb(void *vcbdata, Solvable *s, Repodata *data, Repokey *key, KeyVal
780758
break;
781759
case REPOKEY_TYPE_ID:
782760
id = kv->id;
783-
if (!ISRELDEP(id) && cbdata->ownspool && id > 1)
761+
if (!ISRELDEP(id) && cbdata->ownspool && id > 1 && (!cbdata->clonepool || data->localpool))
784762
id = putinownpool(cbdata, data, id);
785763
needid = cbdata->needid;
786-
id = needid[ISRELDEP(id) ? RELOFF(id) : id].need;
764+
id = needid[NEEDIDOFF(id)].need;
787765
data_addid(xd, id);
788766
break;
789767
case REPOKEY_TYPE_IDARRAY:
790768
id = kv->id;
791-
if (!ISRELDEP(id) && cbdata->ownspool && id > 1)
769+
if (!ISRELDEP(id) && cbdata->ownspool && id > 1 && (!cbdata->clonepool || data->localpool))
792770
id = putinownpool(cbdata, data, id);
793771
needid = cbdata->needid;
794-
id = needid[ISRELDEP(id) ? RELOFF(id) : id].need;
772+
id = needid[NEEDIDOFF(id)].need;
795773
data_addideof(xd, id, kv->eof);
796774
break;
797775
case REPOKEY_TYPE_STR:
@@ -1191,7 +1169,7 @@ repowriter_write(Repowriter *writer, FILE *fp)
11911169
Pool *pool = repo->pool;
11921170
int i, j, n;
11931171
Solvable *s;
1194-
NeedId *needid;
1172+
NeedId *needid, *needidp;
11951173
int nstrings, nrels;
11961174
unsigned int sizeid;
11971175
unsigned int solv_flags;
@@ -1447,6 +1425,8 @@ repowriter_write(Repowriter *writer, FILE *fp)
14471425
/* 1: use global pool */
14481426
/* 2: use repodata local pool */
14491427
/* 3: need own pool */
1428+
if (poolusage != 3)
1429+
clonepool = 0;
14501430
if (poolusage == 3)
14511431
{
14521432
spool = &target.spool;
@@ -1456,6 +1436,7 @@ repowriter_write(Repowriter *writer, FILE *fp)
14561436
{
14571437
stringpool_free(spool);
14581438
stringpool_clone(spool, &pool->ss);
1439+
cbdata.clonepool = 1;
14591440
}
14601441
cbdata.ownspool = spool;
14611442
}
@@ -1483,6 +1464,7 @@ repowriter_write(Repowriter *writer, FILE *fp)
14831464
#if 0
14841465
fprintf(stderr, "poolusage: %d\n", poolusage);
14851466
fprintf(stderr, "dirpoolusage: %d\n", dirpoolusage);
1467+
fprintf(stderr, "clonepool: %d\n", clonepool);
14861468
fprintf(stderr, "nkeys: %d\n", target.nkeys);
14871469
for (i = 1; i < target.nkeys; i++)
14881470
fprintf(stderr, " %2d: %s[%d] %d %d %d\n", i, pool_id2str(pool, target.keys[i].name), target.keys[i].name, target.keys[i].type, target.keys[i].size, target.keys[i].storage);
@@ -1659,7 +1641,8 @@ for (i = 1; i < target.nkeys; i++)
16591641
keymap[i] = keyused[keymap[i]];
16601642
keyused = solv_free(keyused);
16611643

1662-
/* increment needid of the used keys, they are already mapped to
1644+
1645+
/* increment needid of the keys, they are already mapped to
16631646
* the correct string pool */
16641647
for (i = 1; i < target.nkeys; i++)
16651648
{
@@ -1669,6 +1652,72 @@ for (i = 1; i < target.nkeys; i++)
16691652
needid[target.keys[i].type].need++;
16701653
}
16711654

1655+
/********************************************************************/
1656+
1657+
/* increment need id of all relations
1658+
* if we refer to another relation, make sure that the
1659+
* need value is it is bigger than our value so that
1660+
* ordering works.
1661+
*/
1662+
for (i = pool->nrels - 1, needidp = needid + (reloff + i); i > 0; i--, needidp--)
1663+
if (needidp->need)
1664+
break;
1665+
if (i)
1666+
{
1667+
/* we have some relations with a non-zero need */
1668+
Reldep *rd;
1669+
1670+
for (rd = pool->rels + i; i > 1; i--, rd--)
1671+
{
1672+
int need = needid[reloff + i].need;
1673+
if (!need)
1674+
continue;
1675+
id = rd->name;
1676+
if (ISRELDEP(id))
1677+
{
1678+
id = GETRELID(id);
1679+
if (needid[reloff + id].need < need + 1)
1680+
needid[reloff + id].need = need + 1;
1681+
}
1682+
else
1683+
{
1684+
if (cbdata.ownspool && id > 1 && !cbdata.clonepool)
1685+
{
1686+
id = stringpool_str2id(cbdata.ownspool, pool_id2str(pool, id), 1);
1687+
if (id >= cbdata.needid[0].map)
1688+
{
1689+
grow_needid(&cbdata, id);
1690+
needid = cbdata.needid; /* we relocated */
1691+
reloff = needid[0].map; /* we have a new offset */
1692+
}
1693+
}
1694+
needid[id].need++;
1695+
}
1696+
1697+
id = rd->evr;
1698+
if (ISRELDEP(id))
1699+
{
1700+
id = GETRELID(id);
1701+
if (needid[reloff + id].need < need + 1)
1702+
needid[reloff + id].need = need + 1;
1703+
}
1704+
else
1705+
{
1706+
if (cbdata.ownspool && id > 1 && !cbdata.clonepool)
1707+
{
1708+
id = stringpool_str2id(cbdata.ownspool, pool_id2str(pool, id), 1);
1709+
if (id >= cbdata.needid[0].map)
1710+
{
1711+
grow_needid(&cbdata, id);
1712+
needid = cbdata.needid; /* we relocated */
1713+
reloff = needid[0].map; /* we have a new offset */
1714+
}
1715+
}
1716+
needid[id].need++;
1717+
}
1718+
}
1719+
}
1720+
16721721
/********************************************************************/
16731722

16741723
if (dirpool && cbdata.dirused && !cbdata.dirused[0])
@@ -1954,8 +2003,8 @@ fprintf(stderr, "dir %d used %d\n", i, cbdata.dirused ? cbdata.dirused[i] : 1);
19542003
for (i = 0; i < nrels; i++)
19552004
{
19562005
Reldep *ran = pool->rels + (needid[reloff + i].map - reloff);
1957-
write_id(&target, needid[ISRELDEP(ran->name) ? RELOFF(ran->name) : ran->name].need);
1958-
write_id(&target, needid[ISRELDEP(ran->evr) ? RELOFF(ran->evr) : ran->evr].need);
2006+
write_id(&target, needid[NEEDIDOFF(ran->name)].need);
2007+
write_id(&target, needid[NEEDIDOFF(ran->evr)].need);
19592008
write_u8(&target, ran->flags);
19602009
}
19612010

0 commit comments

Comments
 (0)