rpm/taggedfileindex.diff

120 lines
3.6 KiB
Diff

The taggedfileindex patch. Speeds up database searches, but breaks
fingerprint semantics. Needs findfplistexclude.diff.
rh#103204
Index: rpmdb/rpmdb.c
===================================================================
--- rpmdb/rpmdb.c.orig
+++ rpmdb/rpmdb.c
@@ -1215,6 +1215,16 @@ int rpmdbVerify(const char * prefix)
return rc;
}
+static inline unsigned int taghash(const char *s)
+{
+ int c;
+ unsigned int r = 0;
+ while ((c = *(const unsigned char *)s++) != 0)
+ if (c != '/')
+ r += (r << 3) + c;
+ return ((r & 0x7fff) | 0x8000) << 16;
+}
+
/**
* Find file matches in database.
* @param db rpm database
@@ -1294,6 +1304,11 @@ if (key->size == 0) key->size++; /* XXX
if (rc == 0)
(void) dbt2set(dbi, data, &allMatches);
+ /* strip off directory tags */
+ if (allMatches != NULL)
+ for (i = 0; i < allMatches->count; i++)
+ if (allMatches->recs[i].tagNum & 0x80000000)
+ allMatches->recs[i].tagNum &= 0x0000ffff;
xx = dbiCclose(dbi, dbcursor, 0);
dbcursor = NULL;
} else
@@ -2411,7 +2426,7 @@ static void rpmdbSortIterator(/*@null@*/
}
/*@-bounds@*/ /* LCL: segfault */
-static int rpmdbGrowIterator(/*@null@*/ rpmdbMatchIterator mi, int fpNum, unsigned int exclude)
+static int rpmdbGrowIterator(/*@null@*/ rpmdbMatchIterator mi, int fpNum, unsigned int exclude, unsigned int tag)
/*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
/*@modifies mi, rpmGlobalMacroContext, fileSystem, internalState @*/
{
@@ -2459,10 +2474,16 @@ static int rpmdbGrowIterator(/*@null@*/
set = NULL;
(void) dbt2set(dbi, data, &set);
- /* prune the set against exclude */
+ /* prune the set against exclude and tag */
for (i = j = 0; i < set->count; i++) {
if (exclude && set->recs[i].hdrNum == exclude)
continue;
+ if (set->recs[i].tagNum & 0x80000000) {
+ /* tagged entry */
+ if ((set->recs[i].tagNum & 0xffff0000) != tag)
+ continue;
+ set->recs[i].tagNum &= 0x0000ffff;
+ }
if (i != j)
set->recs[j] = set->recs[i];
j++;
@@ -2987,7 +3008,9 @@ DBT * data = alloca(sizeof(*data));
HFD_t hfd = headerFreeData;
sigset_t signalMask;
const char ** baseNames;
- rpmTagType bnt;
+ const char ** dirNames;
+ int_32 * dirIndexes, *dirs;
+ rpmTagType bnt, dit, dnt;
int count = 0;
dbiIndex dbi;
int dbix;
@@ -3027,6 +3050,13 @@ memset(data, 0, sizeof(*data));
*/
xx = hge(h, RPMTAG_BASENAMES, &bnt, (void **) &baseNames, &count);
+ xx = hge(h, RPMTAG_DIRINDEXES, &dit, (void **) &dirIndexes, NULL);
+ xx = hge(h, RPMTAG_DIRNAMES, &dnt, (void **) &dirNames, NULL);
+
+ /* save dirIndexes, because expandFilelist may free it */
+ dirs = alloca(count * sizeof(*dirs));
+ for (xx = 0; xx < count; xx++)
+ dirs[xx] = dirIndexes[xx];
if (_noDirTokens)
expandFilelist(h);
@@ -3240,6 +3270,11 @@ data->size = 0;
*/
rec->tagNum = i;
switch (dbi->dbi_rpmtag) {
+ case RPMTAG_BASENAMES:
+ /* tag index entry with directory hash */
+ if (i < 0x010000)
+ rec->tagNum |= taghash(dirNames[dirs[i]]);
+ /*@switchbreak@*/ break;
case RPMTAG_PUBKEYS:
/*@switchbreak@*/ break;
case RPMTAG_FILEMD5S:
@@ -3414,6 +3449,8 @@ if (key->size == 0) key->size++; /* XXX
}
exit:
+ dirIndexes = hfd(dirIndexes, dit);
+ dirNames = hfd(dirNames, dnt);
(void) unblockSignals(db, &signalMask);
return ret;
@@ -3495,7 +3532,7 @@ if (key->size == 0) key->size++; /* XXX
if (!exclude && skipDir(fpList[i].entry->dirName))
continue;
- xx = rpmdbGrowIterator(mi, i, exclude);
+ xx = rpmdbGrowIterator(mi, i, exclude, taghash(fpList[i].entry->dirName));
}