The following commit has been merged in the master branch:
commit 47e241d719b5d286fc6c21d3ace624ab9fdecbfe
Author: Guillem Jover <[email protected]>
Date:   Tue Jan 25 16:57:05 2011 +0100

    libdpkg: Add new struct pkgset and use it for the in-core package database
    
    This will allow to bundle together several pkginfo instances into a
    single pkgset sharing the same package name.
    
    [[email protected]: (Sponsored-by: Linaro Limited)
     - Do not move name from pkginfo to pkgset yet.
     - Switch pkg_db_find() and pkg_db_iter_next() back to return pkginfo *,
       although initial pkg_db_iter_next() re-implementation discarded. ]
    
    Signed-off-by: Guillem Jover <[email protected]>

diff --git a/lib/dpkg/dpkg-db.h b/lib/dpkg/dpkg-db.h
index e196f71..9471c32 100644
--- a/lib/dpkg/dpkg-db.h
+++ b/lib/dpkg/dpkg-db.h
@@ -162,7 +162,9 @@ struct perpackagestate;
  * Note: Usually referred in the code as pig.
  */
 struct pkginfo {
-  struct pkginfo *next;
+  struct pkgset *set;
+  struct pkginfo *arch_next;
+
   const char *name;
   enum pkgwant {
     want_unknown, want_install, want_hold, want_deinstall, want_purge,
@@ -210,6 +212,15 @@ struct pkginfo {
   struct trigpend *trigpend_head;
 };
 
+/**
+ * Node describing a package set sharing the same package name.
+ */
+struct pkgset {
+  struct pkgset *next;
+  const char *name;
+  struct pkginfo pkg;
+};
+
 /*** from dbdir.c ***/
 
 const char *dpkg_db_set_dir(const char *dir);
@@ -245,6 +256,7 @@ void modstatdb_shutdown(void);
 
 /*** from database.c ***/
 
+void pkgset_blank(struct pkgset *set);
 void pkg_blank(struct pkginfo *pp);
 void pkgbin_blank(struct pkgbin *pifp);
 bool pkg_is_informative(struct pkginfo *pkg, struct pkgbin *info);
diff --git a/lib/dpkg/parse.c b/lib/dpkg/parse.c
index 5d254b4..eea4019 100644
--- a/lib/dpkg/parse.c
+++ b/lib/dpkg/parse.c
@@ -514,7 +514,7 @@ parse_close(struct parsedb_state *ps)
 int parsedb(const char *filename, enum parsedbflags flags,
             struct pkginfo **donep)
 {
-  struct pkginfo tmp_pkg;
+  struct pkgset tmp_set;
   struct pkginfo *new_pkg, *db_pkg;
   struct pkgbin *new_pkgbin, *db_pkgbin;
   struct pkg_parse_object pkg_obj;
@@ -528,7 +528,7 @@ int parsedb(const char *filename, enum parsedbflags flags,
 
   parse_open(&ps, filename, flags);
 
-  new_pkg = &tmp_pkg;
+  new_pkg = &tmp_set.pkg;
   if (flags & pdb_recordavailable)
     new_pkgbin = &new_pkg->available;
   else
@@ -545,7 +545,7 @@ int parsedb(const char *filename, enum parsedbflags flags,
   /* Loop per package. */
   for (;;) {
     memset(fieldencountered, 0, sizeof(fieldencountered));
-    pkg_blank(new_pkg);
+    pkgset_blank(&tmp_set);
 
     if (!parse_stanza(&ps, &fs, pkg_parse_field, &pkg_obj))
       break;
diff --git a/lib/dpkg/pkg-db.c b/lib/dpkg/pkg-db.c
index d93dc0f..60f4449 100644
--- a/lib/dpkg/pkg-db.c
+++ b/lib/dpkg/pkg-db.c
@@ -36,7 +36,7 @@
  * sizeof(void *) * 8063 (i.e. less than 32 KiB on 32bit systems). */
 #define BINS 8191
 
-static struct pkginfo *bins[BINS];
+static struct pkgset *bins[BINS];
 static int npackages;
 
 #define FNV_offset_basis 2166136261ul
@@ -60,7 +60,7 @@ static unsigned int hash(const char *name) {
 struct pkginfo *
 pkg_db_find(const char *inname)
 {
-  struct pkginfo **pointerp, *newpkg;
+  struct pkgset **pointerp, *newpkg;
   char *name = m_strdup(inname), *p;
 
   p= name;
@@ -69,17 +69,21 @@ pkg_db_find(const char *inname)
   pointerp= bins + (hash(name) % (BINS));
   while (*pointerp && strcasecmp((*pointerp)->name,name))
     pointerp= &(*pointerp)->next;
-  if (*pointerp) { free(name); return *pointerp; }
+  if (*pointerp) {
+    free(name);
+    return &(*pointerp)->pkg;
+  }
 
-  newpkg= nfmalloc(sizeof(struct pkginfo));
-  pkg_blank(newpkg);
+  newpkg = nfmalloc(sizeof(struct pkgset));
+  pkgset_blank(newpkg);
   newpkg->name= nfstrsave(name);
   newpkg->next= NULL;
+  newpkg->pkg.name = newpkg->name;
   *pointerp= newpkg;
   npackages++;
 
   free(name);
-  return newpkg;
+  return &newpkg->pkg;
 }
 
 int
@@ -107,11 +111,23 @@ struct pkginfo *
 pkg_db_iter_next(struct pkgiterator *i)
 {
   struct pkginfo *r;
+
   while (!i->pigp) {
     if (i->nbinn >= BINS) return NULL;
-    i->pigp= bins[i->nbinn++];
+    if (bins[i->nbinn])
+      i->pigp = &bins[i->nbinn]->pkg;
+    i->nbinn++;
   }
-  r= i->pigp; i->pigp= r->next; return r;
+
+  r = i->pigp;
+  if (r->arch_next)
+    i->pigp = r->arch_next;
+  else if (r->set->next)
+    i->pigp = &r->set->next->pkg;
+  else
+    i->pigp = NULL;
+
+  return r;
 }
 
 void
@@ -135,7 +151,7 @@ void
 pkg_db_report(FILE *file)
 {
   int i, c;
-  struct pkginfo *pkg;
+  struct pkgset *pkg;
   int *freq;
 
   freq= m_malloc(sizeof(int)*npackages+1);
diff --git a/lib/dpkg/pkg.c b/lib/dpkg/pkg.c
index 3ae7d27..d2abd04 100644
--- a/lib/dpkg/pkg.c
+++ b/lib/dpkg/pkg.c
@@ -49,6 +49,8 @@ pkgbin_blank(struct pkgbin *pkgbin)
 void
 pkg_blank(struct pkginfo *pkg)
 {
+       pkg->set = NULL;
+       pkg->arch_next = NULL;
        pkg->name = NULL;
        pkg->status = stat_notinstalled;
        pkg->eflag = eflag_ok;
@@ -67,6 +69,14 @@ pkg_blank(struct pkginfo *pkg)
        pkgbin_blank(&pkg->available);
 }
 
+void
+pkgset_blank(struct pkgset *set)
+{
+       set->name = NULL;
+       pkg_blank(&set->pkg);
+       set->pkg.set = set;
+}
+
 static int
 nes(const char *s)
 {

-- 
dpkg's main repository


-- 
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]

Reply via email to