Separate match iterator allocation vs initialization
authorPanu Matilainen <pmatilai@redhat.com>
Tue, 26 Oct 2010 06:54:55 +0000 (09:54 +0300)
committerPanu Matilainen <pmatilai@redhat.com>
Tue, 26 Oct 2010 06:54:55 +0000 (09:54 +0300)
- There's exactly one spot within rpm which needs the former behavior
  of rpmdbInitIterator() on a secondary index with keyp of NULL:
  rpmFindBaseNamesInDB(): it wants an empty iterator on RPMDBI_BASENAMES,
  which is then extended as it progresses. Starting with commit
  c70e076e088589f65160c05ee7cc8db0b3db6d7e, rpmdbInitIterator()
  however returns the actual index in that case, which is not
  optimal for rpmFindBaseNamesInDB(). Handle the basenames in db
  as the special case it is, and have it explicitly create an
  empty iterator with the new call.

lib/rpmdb.c
lib/rpmdb_internal.h
lib/transaction.c

index d281094..ce7c705 100644 (file)
@@ -2003,6 +2003,42 @@ int rpmdbAppendIterator(rpmdbMatchIterator mi, const int * hdrNums, int nHdrNums
     return 0;
 }
 
+rpmdbMatchIterator rpmdbNewIterator(rpmdb db, rpmDbiTagVal dbitag)
+{
+    rpmdbMatchIterator mi = NULL;
+
+    if (rpmdbOpenIndex(db, dbitag, 0) == NULL)
+       return NULL;
+
+    mi = xcalloc(1, sizeof(*mi));
+    mi->mi_keyp = NULL;
+    mi->mi_keylen = 0;
+    mi->mi_set = NULL;
+    mi->mi_db = rpmdbLink(db);
+    mi->mi_rpmtag = dbitag;
+
+    mi->mi_dbc = NULL;
+    mi->mi_setx = 0;
+    mi->mi_h = NULL;
+    mi->mi_sorted = 0;
+    mi->mi_cflags = 0;
+    mi->mi_modified = 0;
+    mi->mi_prevoffset = 0;
+    mi->mi_offset = 0;
+    mi->mi_filenum = 0;
+    mi->mi_nre = 0;
+    mi->mi_re = NULL;
+
+    mi->mi_ts = NULL;
+    mi->mi_hdrchk = NULL;
+
+    /* Chain cursors for teardown on abnormal exit. */
+    mi->mi_next = rpmmiRock;
+    rpmmiRock = mi;
+
+    return mi;
+};
+
 rpmdbMatchIterator rpmdbInitIterator(rpmdb db, rpmDbiTagVal rpmtag,
                const void * keyp, size_t keylen)
 {
@@ -2139,31 +2175,10 @@ rpmdbMatchIterator rpmdbInitIterator(rpmdb db, rpmDbiTagVal rpmtag,
        }
     }
 
-    mi = xcalloc(1, sizeof(*mi));
+    mi = rpmdbNewIterator(db, rpmtag);
     mi->mi_keyp = mi_keyp;
     mi->mi_keylen = keylen;
     mi->mi_set = set;
-    mi->mi_db = rpmdbLink(db);
-    mi->mi_rpmtag = rpmtag;
-
-    /* Chain cursors for teardown on abnormal exit. */
-    mi->mi_next = rpmmiRock;
-    rpmmiRock = mi;
-
-    mi->mi_dbc = NULL;
-    mi->mi_setx = 0;
-    mi->mi_h = NULL;
-    mi->mi_sorted = 0;
-    mi->mi_cflags = 0;
-    mi->mi_modified = 0;
-    mi->mi_prevoffset = 0;
-    mi->mi_offset = 0;
-    mi->mi_filenum = 0;
-    mi->mi_nre = 0;
-    mi->mi_re = NULL;
-
-    mi->mi_ts = NULL;
-    mi->mi_hdrchk = NULL;
 
     if (rpmtag != RPMDBI_PACKAGES && keyp == NULL) {
         rpmdbSortIterator(mi);
index 1b691a2..9447d05 100644 (file)
@@ -75,6 +75,16 @@ void rpmdbSortIterator(rpmdbMatchIterator mi);
  */
 int rpmdbPruneIterator(rpmdbMatchIterator mi, intHash hdrNums);
 
+/** \ingroup rpmdb
+ * Create a new, empty match iterator (for purposes of extending it
+ * through other means)
+ * @param db           rpm database
+ * @param dbitag       database index tag
+ * @return             empty match iterator
+ */
+RPM_GNUC_INTERNAL
+rpmdbMatchIterator rpmdbNewIterator(rpmdb db, rpmDbiTagVal dbitag);
+
 #ifndef __APPLE__
 /**
  *  * Mergesort, same arguments as qsort(2).
index ee3f78f..c7e6849 100644 (file)
@@ -878,7 +878,7 @@ rpmdbMatchIterator rpmFindBaseNamesInDB(rpmts ts, uint64_t fileCount)
     rpmStringSet baseNames = rpmStringSetCreate(fileCount, 
                                        hashFunctionString, strcmp, NULL);
 
-    mi = rpmdbInitIterator(rpmtsGetRdb(ts), RPMDBI_BASENAMES, NULL, 0);
+    mi = rpmdbNewIterator(rpmtsGetRdb(ts), RPMDBI_BASENAMES);
 
     pi = rpmtsiInit(ts);
     while ((p = rpmtsiNext(pi, 0)) != NULL) {