25f00b6cb5
Copy from Base:System/rpm based on submit request 18841 from user mlschroe OBS-URL: https://build.opensuse.org/request/show/18841 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/rpm?expand=0&rev=84
188 lines
5.0 KiB
Diff
188 lines
5.0 KiB
Diff
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) */
|