rpm/taggedfileindex.diff

188 lines
5.0 KiB
Diff
Raw Normal View History

The taggedfileindex patch. Speeds up database searches, but breaks
fingerprint semantics.
rh#103204
Index: lib/rpmdb.c
===================================================================
--- lib/rpmdb.c.orig
+++ lib/rpmdb.c
@@ -1107,6 +1107,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
@@ -1169,6 +1179,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
@@ -2172,7 +2187,7 @@ void rpmdbSortIterator(rpmdbMatchIterato
}
/* LCL: segfault */
-static int rpmdbGrowIterator(rpmdbMatchIterator mi)
+static int rpmdbGrowIterator(rpmdbMatchIterator mi, unsigned int tag)
{
DBC * dbcursor;
DBT * key;
@@ -2222,6 +2237,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 {
@@ -2403,7 +2439,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);
}
/*
@@ -2798,8 +2842,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;
@@ -2891,6 +2943,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);
@@ -2976,6 +3032,9 @@ cont:
if (ret == 0) {
headerSetInstance(h, hdrNum);
}
+
+ rpmtdFreeData(&dn);
+ rpmtdFreeData(&di);
}
exit:
Index: lib/rpmdb_internal.h
===================================================================
--- lib/rpmdb_internal.h.orig
+++ lib/rpmdb_internal.h
@@ -540,6 +540,9 @@ unsigned int dbiIndexRecordFileNumber(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.
Index: lib/transaction.c
===================================================================
--- lib/transaction.c.orig
+++ lib/transaction.c
@@ -609,9 +609,12 @@ rpmdbMatchIterator rpmFindBaseNamesInDB(
rpmdbMatchIterator mi;
int i, 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);
@@ -629,18 +632,25 @@ rpmdbMatchIterator rpmFindBaseNamesInDB(
while ((i = 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) */