[Rpm-maint] [Suse patch] Tagged fileindexes

Panu Matilainen pmatilai at redhat.com
Fri Jun 8 11:34:23 UTC 2007


The speed-up from this is not insignificant based on my tests, but is it 
enough of a justification to break semantics? For 4.4.2.1 probably not a 
safe thing... beyond that, I think we should have a good hard look at the 
whole fingerprinting stuff :)

 	- Panu -
---

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
@@ -1223,6 +1223,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
@@ -1302,6 +1312,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
@@ -2408,7 +2423,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 @*/
  {
@@ -2456,10 +2471,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);
@@ -3243,6 +3273,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:
@@ -3417,6 +3452,8 @@ if (key->size == 0) key->size++;	/* XXX
      }

  exit:
+    dirIndexes = hfd(dirIndexes, dit);
+    dirNames = hfd(dirNames, dnt);
      (void) unblockSignals(db, &signalMask);

      return ret;
@@ -3505,7 +3542,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));

      }




More information about the Rpm-maint mailing list