rpm/taggedfileindex.diff
2010-03-26 10:56:28 +00:00

182 lines
4.9 KiB
Diff

The taggedfileindex patch. Speeds up database searches, but breaks
fingerprint semantics.
rh#103204
--- ./lib/rpmdb.c.orig 2010-03-25 14:43:41.000000000 +0000
+++ ./lib/rpmdb.c 2010-03-25 15:15:14.000000000 +0000
@@ -1122,6 +1122,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
@@ -1181,6 +1191,11 @@ static int rpmdbFindByFile(rpmdb db, con
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
@@ -2182,7 +2197,7 @@ void rpmdbSortIterator(rpmdbMatchIterato
}
}
-static int rpmdbGrowIterator(rpmdbMatchIterator mi)
+static int rpmdbGrowIterator(rpmdbMatchIterator mi, unsigned int tag)
{
DBC * dbcursor;
DBT * key;
@@ -2232,6 +2247,27 @@ static int rpmdbGrowIterator(rpmdbMatchI
dbcursor = NULL;
#endif
+ if (tag) {
+ int i, j;
+ /* prune the set against the tag */
+ for (i = j = 0; i < set->count; i++) {
+ 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++;
+ }
+ set->count = j;
+ if (j == 0) {
+ set = dbiFreeIndexSet(set);
+ return DB_NOTFOUND;
+ }
+ }
+
if (mi->mi_set == NULL) {
mi->mi_set = set;
} else {
@@ -2413,7 +2449,15 @@ int rpmdbExtendIterator(rpmdbMatchIterat
{
mi->mi_key.data = (void *) keyp;
mi->mi_key.size = keylen ? keylen : strlen(keyp);
- return rpmdbGrowIterator(mi);
+ return rpmdbGrowIterator(mi, 0);
+}
+
+int rpmdbExtendIteratorDirtag(rpmdbMatchIterator mi,
+ const void * keyp, size_t keylen, const char *dirname)
+{
+ mi->mi_key.data = (void *) keyp;
+ mi->mi_key.size = keylen ? keylen : strlen(keyp);
+ return rpmdbGrowIterator(mi, dirname ? taghash(dirname) : 0);
}
/*
@@ -2808,8 +2852,16 @@ int rpmdbAdd(rpmdb db, int iid, Header h
if (hdrNum)
{
+ struct rpmtd_s dn, di;
+ const char ** dirNames;
+ uint32_t * dirIndexes;
dbiIndexItem rec = dbiIndexNewItem(hdrNum, 0);
+ headerGet(h, RPMTAG_DIRNAMES, &dn, HEADERGET_MINMEM);
+ headerGet(h, RPMTAG_DIRINDEXES, &di, HEADERGET_MINMEM);
+ dirNames = dn.data;
+ dirIndexes = di.data;
+
if (dbiTags.tags != NULL)
for (dbix = 0; dbix < dbiTags.max; dbix++) {
rpmTag rpmtag;
@@ -2901,6 +2953,10 @@ int rpmdbAdd(rpmdb db, int iid, Header h
*/
i = rec->tagNum = rpmtdGetIndex(&tagdata);
switch (rpmtag) {
+ case RPMTAG_BASENAMES:
+ if (i < 0x010000)
+ rec->tagNum |= taghash(dirNames[dirIndexes[i]]);
+ break;
case RPMTAG_REQUIRENAME: {
/* Filter out install prerequisites. */
rpm_flag_t *rflag = rpmtdNextUint32(&reqflags);
@@ -2986,6 +3042,9 @@ cont:
if (ret == 0) {
headerSetInstance(h, hdrNum);
}
+
+ rpmtdFreeData(&dn);
+ rpmtdFreeData(&di);
}
exit:
--- ./lib/rpmdb_internal.h.orig 2009-12-07 14:36:49.000000000 +0000
+++ ./lib/rpmdb_internal.h 2010-03-25 15:14:38.000000000 +0000
@@ -542,6 +542,9 @@ const char *rpmdbHome(rpmdb db);
int rpmdbExtendIterator(rpmdbMatchIterator mi,
const void * keyp, size_t keylen);
+int rpmdbExtendIteratorDirtag(rpmdbMatchIterator mi,
+ const void * keyp, size_t keylen, const char *);
+
/** \ingroup rpmdb
* sort the iterator by (recnum, filenum)
* Return database iterator.
--- ./lib/transaction.c.orig 2010-03-25 14:38:27.000000000 +0000
+++ ./lib/transaction.c 2010-03-25 15:14:38.000000000 +0000
@@ -848,9 +848,12 @@ rpmdbMatchIterator rpmFindBaseNamesInDB(
rpmdbMatchIterator mi;
int xx;
const char * baseName;
+ const char * dirName;
+#if 0
rpmStringSet baseNames = rpmStringSetCreate(fileCount,
hashFunctionString, strcmp, NULL);
+#endif
mi = rpmdbInitIterator(rpmtsGetRdb(ts), RPMTAG_BASENAMES, NULL, 0);
@@ -868,18 +871,25 @@ rpmdbMatchIterator rpmFindBaseNamesInDB(
while (rpmfiNext(fi) >= 0) {
size_t keylen;
baseName = rpmfiBN(fi);
+ dirName = rpmfiDN(fi);
+#if 0
if (rpmStringSetHasEntry(baseNames, baseName))
continue;
+#endif
keylen = strlen(baseName);
if (keylen == 0)
keylen++; /* XXX "/" fixup. */
- xx = rpmdbExtendIterator(mi, baseName, keylen);
+ xx = rpmdbExtendIteratorDirtag(mi, baseName, keylen, dirName);
+#if 0
rpmStringSetAddEntry(baseNames, baseName);
+#endif
}
}
pi = rpmtsiFree(pi);
+#if 0
rpmStringSetFree(baseNames);
+#endif
rpmdbSortIterator(mi);
/* iterator is now sorted by (recnum, filenum) */