Be as lazy as possible wrt rpmal hash creation
- Separate provides and files hash creation, delay both until the last moment before first valid lookup. In practise, this means the provides hash is created early due to lookups from rpmtsAddInstallElement(), but the big bad file hash creation is delayed until the entire transaction set has been more-or-less populated. Which means we have a better idea about the necessary hash table size, meaning fewer hash resizes, resulting in good deal faster execution with no downsides - if something happened to trigger an early file lookup it'll all still work, just slower.
This commit is contained in:
parent
bee348b5d1
commit
d5dd3abe09
48
lib/rpmal.c
48
lib/rpmal.c
|
@ -266,41 +266,48 @@ void rpmalAdd(rpmal al, rpmte p)
|
|||
assert(dspool == NULL || dspool == al->pool);
|
||||
}
|
||||
|
||||
if (al->providesHash != NULL) { // index is already created
|
||||
/* Try to be lazy as delayed hash creation is cheaper */
|
||||
if (al->providesHash != NULL)
|
||||
rpmalAddProvides(al, pkgNum, alp->provides);
|
||||
if (al->fileHash != NULL)
|
||||
rpmalAddFiles(al, pkgNum, alp->fi);
|
||||
}
|
||||
|
||||
assert(((rpmalNum)(alp - al->list)) == pkgNum);
|
||||
}
|
||||
|
||||
static void rpmalMakeIndex(rpmal al)
|
||||
static void rpmalMakeFileIndex(rpmal al)
|
||||
{
|
||||
availablePackage alp;
|
||||
int i;
|
||||
int providesCnt = 0;
|
||||
int fileCnt = 0;
|
||||
int i, fileCnt = 0;
|
||||
|
||||
if (al == NULL || al->list == NULL) return;
|
||||
if (al->providesHash != NULL || al->fileHash != NULL)
|
||||
return;
|
||||
for (i = 0; i < al->size; i++) {
|
||||
alp = al->list + i;
|
||||
if (alp->provides != NULL)
|
||||
providesCnt += rpmdsCount(alp->provides);
|
||||
if (alp->fi != NULL)
|
||||
fileCnt += rpmfiFC(alp->fi);
|
||||
}
|
||||
al->fileHash = rpmalFileHashCreate(fileCnt/4+128,
|
||||
fileHash, fileCompare, NULL, NULL);
|
||||
for (i = 0; i < al->size; i++) {
|
||||
alp = al->list + i;
|
||||
rpmalAddFiles(al, i, alp->fi);
|
||||
}
|
||||
}
|
||||
|
||||
al->providesHash = rpmalProvidesHashCreate(providesCnt/4+128, sidHash,
|
||||
sidCmp, NULL, NULL);
|
||||
al->fileHash = rpmalFileHashCreate(fileCnt/4+128, fileHash, fileCompare,
|
||||
NULL, NULL);
|
||||
static void rpmalMakeProvidesIndex(rpmal al)
|
||||
{
|
||||
availablePackage alp;
|
||||
int i, providesCnt = 0;
|
||||
|
||||
for (i = 0; i < al->size; i++) {
|
||||
alp = al->list + i;
|
||||
providesCnt += rpmdsCount(alp->provides);
|
||||
}
|
||||
|
||||
al->providesHash = rpmalProvidesHashCreate(providesCnt/4+128,
|
||||
sidHash, sidCmp, NULL, NULL);
|
||||
for (i = 0; i < al->size; i++) {
|
||||
alp = al->list + i;
|
||||
rpmalAddProvides(al, i, alp->provides);
|
||||
rpmalAddFiles(al, i, alp->fi);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -322,6 +329,9 @@ static rpmte * rpmalAllFileSatisfiesDepend(const rpmal al, const char *fileName)
|
|||
fne.baseName = rpmstrPoolId(al->pool, fileName + bnStart, 0);
|
||||
fne.dirName = rpmstrPoolIdn(al->pool, fileName, bnStart, 0);
|
||||
|
||||
if (al->fileHash == NULL)
|
||||
rpmalMakeFileIndex(al);
|
||||
|
||||
rpmalFileHashGetEntry(al->fileHash, fne, &result, &resultCnt, NULL);
|
||||
|
||||
if (resultCnt > 0) {
|
||||
|
@ -359,9 +369,6 @@ rpmte * rpmalAllSatisfiesDepend(const rpmal al, const rpmds ds)
|
|||
if (al == NULL || ds == NULL || (nameId = rpmdsNId(ds)) == 0)
|
||||
return ret;
|
||||
|
||||
if (al->providesHash == NULL && al->fileHash == NULL)
|
||||
rpmalMakeIndex(al);
|
||||
|
||||
obsolete = (rpmdsTagN(ds) == RPMTAG_OBSOLETENAME);
|
||||
name = rpmstrPoolStr(al->pool, nameId);
|
||||
if (!obsolete && *name == '/') {
|
||||
|
@ -375,6 +382,9 @@ rpmte * rpmalAllSatisfiesDepend(const rpmal al, const rpmds ds)
|
|||
ret = _free(ret);
|
||||
}
|
||||
|
||||
if (al->providesHash == NULL)
|
||||
rpmalMakeProvidesIndex(al);
|
||||
|
||||
rpmalProvidesHashGetEntry(al->providesHash, nameId, &result,
|
||||
&resultCnt, NULL);
|
||||
|
||||
|
|
Loading…
Reference in New Issue