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]