summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAurelien Foret <aurelien@archlinux.org>2005-04-23 19:18:31 +0200
committerAurelien Foret <aurelien@archlinux.org>2005-04-23 19:18:31 +0200
commite2b474b1309594c610a2cf25f35b349575d88223 (patch)
tree47e19d9745c290cca2b5a8fb3bee1d6150a41b59
parente56980597b90b5107f577c25b25c1a0818d61d7a (diff)
downloadpacman-e2b474b1309594c610a2cf25f35b349575d88223.tar.gz
pacman-e2b474b1309594c610a2cf25f35b349575d88223.tar.xz
rework the cache handling to avoid as much as possible calls to db_scan()
-rw-r--r--lib/libalpm/add.c36
-rw-r--r--lib/libalpm/cache.c55
-rw-r--r--lib/libalpm/cache.h2
-rw-r--r--lib/libalpm/package.c39
-rw-r--r--lib/libalpm/package.h1
-rw-r--r--lib/libalpm/remove.c14
-rw-r--r--lib/libalpm/sync.c65
7 files changed, 150 insertions, 62 deletions
diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c
index 64c06dc4..12546c8e 100644
--- a/lib/libalpm/add.c
+++ b/lib/libalpm/add.c
@@ -273,11 +273,13 @@ int add_commit(pmtrans_t *trans, pmdb_t *db)
/* we'll need the full record for backup checks later */
oldpkg = pkg_new();
- STRNCPY(oldpkg->name, info->name, PKG_NAME_LEN);
- STRNCPY(oldpkg->version, info->version, PKG_VERSION_LEN);
- oldpkg->backup = _alpm_list_strdup(info->backup);
- /* ORE
- oldpkg->reason = info->reason;*/
+ if(oldpkg) {
+ STRNCPY(oldpkg->name, info->name, PKG_NAME_LEN);
+ STRNCPY(oldpkg->version, info->version, PKG_VERSION_LEN);
+ oldpkg->backup = _alpm_list_strdup(info->backup);
+ /* ORE
+ oldpkg->reason = info->reason;*/
+ }
/* pre_upgrade scriptlet */
if(info->scriptlet) {
@@ -364,16 +366,15 @@ int add_commit(pmtrans_t *trans, pmdb_t *db)
}*/
/* make an install date (in UTC) */
STRNCPY(info->installdate, asctime(gmtime(&t)), sizeof(info->installdate));
+ _alpm_log(PM_LOG_FLOW2, "adding database entry %s", info->name);
if(db_write(db, info, INFRQ_ALL)) {
_alpm_log(PM_LOG_ERROR, "could not update database entry %s/%s-%s", db->treename, info->name, info->version);
alpm_logaction(NULL, "error updating database for %s-%s!", info->name, info->version);
RET_ERR(PM_ERR_DB_WRITE, -1);
}
- /* ORE
- in case of an installation, then add info in the pkgcache
- in case of an upgrade, then replace the existing one (or just add because
- trans_remove should already has removed it?
- something like db_cache_addpkg(db, pkgdup(info)); (should also free db->grpcache) */
+ if(db_add_pkgincache(db, info) == -1) {
+ _alpm_log(PM_LOG_ERROR, "could not add entry %s in cache", info->name);
+ }
/* update dependency packages' REQUIREDBY fields */
_alpm_log(PM_LOG_FLOW2, "updating dependency packages 'requiredby' fields");
@@ -387,7 +388,7 @@ int add_commit(pmtrans_t *trans, pmdb_t *db)
/* ORE
same thing here: we should browse the cache instead of using db_scan */
- depinfo = db_scan(db, depend.name, INFRQ_DESC|INFRQ_DEPENDS);
+ depinfo = db_get_pkgfromcache(db, depend.name);
if(depinfo == NULL) {
/* look for a provides package */
/* ORE
@@ -399,7 +400,7 @@ int add_commit(pmtrans_t *trans, pmdb_t *db)
* the first one.
*/
/* use the first one */
- depinfo = db_scan(db, ((pmpkg_t *)provides->data)->name, INFRQ_DESC|INFRQ_DEPENDS);
+ depinfo = db_get_pkgfromcache(db, ((pmpkg_t *)provides->data)->name);
FREELISTPTR(provides);
if(depinfo == NULL) {
/* wtf */
@@ -409,15 +410,11 @@ int add_commit(pmtrans_t *trans, pmdb_t *db)
continue;
}
}
- /* ORE
- if depinfo points on a package from the cache, the cache will be updated
- automatically here! */
depinfo->requiredby = pm_list_add(depinfo->requiredby, strdup(info->name));
_alpm_log(PM_LOG_DEBUG, "updating 'requiredby' field for package %s", depinfo->name);
if(db_write(db, depinfo, INFRQ_DEPENDS)) {
_alpm_log(PM_LOG_ERROR, "could not update 'requiredby' database entry %s/%s-%s", db->treename, depinfo->name, depinfo->version);
}
- FREEPKG(depinfo);
}
/* Extract the .tar.gz package */
@@ -640,13 +637,6 @@ int add_commit(pmtrans_t *trans, pmdb_t *db)
}
FREEPKG(oldpkg);
-
- /* cache needs to be rebuilt */
- /* ORE
- cache should be updated and never freed/reloaded from scratch each time a
- package is added!!! */
- db_free_pkgcache(db);
-
}
/* run ldconfig if it exists */
diff --git a/lib/libalpm/cache.c b/lib/libalpm/cache.c
index a44842d6..3e1c230a 100644
--- a/lib/libalpm/cache.c
+++ b/lib/libalpm/cache.c
@@ -64,7 +64,7 @@ int db_load_pkgcache(pmdb_t *db)
void db_free_pkgcache(pmdb_t *db)
{
- if(db == NULL || db->pkgcache == NULL) {
+ if(db == NULL) {
return;
}
@@ -88,6 +88,57 @@ PMList *db_get_pkgcache(pmdb_t *db)
return(db->pkgcache);
}
+int db_add_pkgincache(pmdb_t *db, pmpkg_t *pkg)
+{
+ pmpkg_t *newpkg;
+
+ _alpm_log(PM_LOG_FUNCTION, "[db_add_pkgincache] called");
+
+ if(db == NULL || pkg == NULL) {
+ return(-1);
+ }
+
+ newpkg = pkg_dup(pkg);
+ if(newpkg == NULL) {
+ return(-1);
+ }
+ db->pkgcache = pm_list_add_sorted(db->pkgcache, newpkg, pkg_cmp);
+
+ db_free_grpcache(db);
+
+ return(0);
+}
+
+int db_remove_pkgfromcache(pmdb_t *db, char *name)
+{
+ PMList *i;
+ int found = 0;
+
+ if(db == NULL || name == NULL || strlen(name) == 0) {
+ return(-1);
+ }
+
+ _alpm_log(PM_LOG_FUNCTION, "[db_remove_pkgfromcache] called");
+
+ for(i = db->pkgcache; i && !found; i = i->next) {
+ if(strcmp(((pmpkg_t *)i->data)->name, name) == 0) {
+ _alpm_log(PM_LOG_DEBUG, "removing entry %s from \"%s\" cache", name, db->treename);
+ db->pkgcache = _alpm_list_remove(db->pkgcache, i);
+ /* ORE
+ MLK: list_remove() does not free properly an entry from a packages list */
+ found = 1;
+ }
+ }
+
+ if(!found) {
+ return(-1);
+ }
+
+ db_free_grpcache(db);
+
+ return(0);
+}
+
pmpkg_t *db_get_pkgfromcache(pmdb_t *db, char *target)
{
PMList *i;
@@ -158,7 +209,7 @@ void db_free_grpcache(pmdb_t *db)
{
PMList *lg;
- if(db == NULL || db->grpcache == NULL) {
+ if(db == NULL) {
return;
}
diff --git a/lib/libalpm/cache.h b/lib/libalpm/cache.h
index b8897322..805d5d30 100644
--- a/lib/libalpm/cache.h
+++ b/lib/libalpm/cache.h
@@ -29,6 +29,8 @@
/* packages */
int db_load_pkgcache(pmdb_t *db);
void db_free_pkgcache(pmdb_t *db);
+int db_add_pkgincache(pmdb_t *db, pmpkg_t *pkg);
+int db_remove_pkgfromcache(pmdb_t *db, char *name);
PMList *db_get_pkgcache(pmdb_t *db);
pmpkg_t *db_get_pkgfromcache(pmdb_t *db, char *target);
/* groups */
diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c
index 0d106893..b5e5bf36 100644
--- a/lib/libalpm/package.c
+++ b/lib/libalpm/package.c
@@ -71,6 +71,45 @@ pmpkg_t *pkg_new()
return(pkg);
}
+pmpkg_t *pkg_dup(pmpkg_t *pkg)
+{
+ pmpkg_t* newpkg = NULL;
+
+ newpkg = (pmpkg_t *)malloc(sizeof(pmpkg_t));
+ if(newpkg == NULL) {
+ return(NULL);
+ }
+
+ STRNCPY(newpkg->name, pkg->name, PKG_NAME_LEN);
+ STRNCPY(newpkg->version, pkg->version, PKG_VERSION_LEN);
+ STRNCPY(newpkg->desc, pkg->desc, PKG_DESC_LEN);
+ STRNCPY(newpkg->url, pkg->url, PKG_URL_LEN);
+ STRNCPY(newpkg->license, pkg->license, PKG_LICENSE_LEN);
+ STRNCPY(newpkg->builddate, pkg->builddate, PKG_DATE_LEN);
+ STRNCPY(newpkg->installdate, pkg->installdate, PKG_DATE_LEN);
+ STRNCPY(newpkg->packager, pkg->packager, PKG_PACKAGER_LEN);
+ STRNCPY(newpkg->md5sum, pkg->md5sum, PKG_MD5SUM_LEN);
+ STRNCPY(newpkg->arch, pkg->arch, PKG_ARCH_LEN);
+ newpkg->size = pkg->size;
+ newpkg->force = pkg->force;
+ newpkg->scriptlet = pkg->scriptlet;
+ newpkg->reason = pkg->reason;
+ newpkg->requiredby = _alpm_list_strdup(pkg->requiredby);
+ newpkg->conflicts = _alpm_list_strdup(pkg->conflicts);
+ newpkg->files = _alpm_list_strdup(pkg->files);
+ newpkg->backup = _alpm_list_strdup(pkg->backup);
+ newpkg->depends = _alpm_list_strdup(pkg->depends);
+ newpkg->groups = _alpm_list_strdup(pkg->groups);
+ newpkg->provides = _alpm_list_strdup(pkg->provides);
+ newpkg->replaces = _alpm_list_strdup(pkg->replaces);
+ /* internal */
+ newpkg->origin = pkg->origin;
+ newpkg->data = (newpkg->origin == PKG_FROM_FILE) ? strdup(pkg->data) : pkg->data;
+ newpkg->infolevel = pkg->infolevel;
+
+ return(newpkg);
+}
+
void pkg_free(pmpkg_t *pkg)
{
if(pkg == NULL) {
diff --git a/lib/libalpm/package.h b/lib/libalpm/package.h
index aedb9b63..105a80aa 100644
--- a/lib/libalpm/package.h
+++ b/lib/libalpm/package.h
@@ -80,6 +80,7 @@ typedef struct __pmpkg_t {
} while(0)
pmpkg_t* pkg_new();
+pmpkg_t *pkg_dup(pmpkg_t *pkg);
void pkg_free(pmpkg_t *pkg);
pmpkg_t *pkg_load(char *pkgfile);
int pkg_cmp(const void *p1, const void *p2);
diff --git a/lib/libalpm/remove.c b/lib/libalpm/remove.c
index 83a745b1..3a2eab93 100644
--- a/lib/libalpm/remove.c
+++ b/lib/libalpm/remove.c
@@ -211,8 +211,12 @@ int remove_commit(pmtrans_t *trans, pmdb_t *db)
/* remove the package from the database */
_alpm_log(PM_LOG_FLOW1, "updating database");
+ _alpm_log(PM_LOG_FLOW2, "removing database entry %s", info->name);
if(db_remove(db, info) == -1) {
- _alpm_log(PM_LOG_ERROR, "failed to remove database entry %s/%s-%s", db->treename, info->name, info->version);
+ _alpm_log(PM_LOG_ERROR, "could not remove database entry %s/%s-%s", db->treename, info->name, info->version);
+ }
+ if(db_remove_pkgfromcache(db, info->name) == -1) {
+ _alpm_log(PM_LOG_ERROR, "could not remove entry %s from cache", info->name);
}
/* update dependency packages' REQUIREDBY fields */
@@ -226,7 +230,7 @@ int remove_commit(pmtrans_t *trans, pmdb_t *db)
continue;
}
- depinfo = db_scan(db, depend.name, INFRQ_DESC|INFRQ_DEPENDS);
+ depinfo = db_get_pkgfromcache(db, depend.name);
if(depinfo == NULL) {
/* look for a provides package */
PMList *provides = _alpm_db_whatprovides(db, depend.name);
@@ -235,7 +239,7 @@ int remove_commit(pmtrans_t *trans, pmdb_t *db)
* the first one.
*/
/* use the first one */
- depinfo = db_scan(db, ((pmpkg_t *)provides->data)->name, INFRQ_DESC|INFRQ_DEPENDS);
+ depinfo = db_get_pkgfromcache(db, ((pmpkg_t *)provides->data)->name);
FREELISTPTR(provides);
if(depinfo == NULL) {
/* wtf */
@@ -256,16 +260,12 @@ int remove_commit(pmtrans_t *trans, pmdb_t *db)
if(db_write(db, depinfo, INFRQ_DEPENDS)) {
_alpm_log(PM_LOG_ERROR, "could not update 'requiredby' database entry %s/%s-%s", db->treename, depinfo->name, depinfo->version);
}
- FREEPKG(depinfo);
}
if(trans->type != PM_TRANS_TYPE_UPGRADE) {
TRANS_CB(trans, PM_TRANS_EVT_REMOVE_DONE, info, NULL);
alpm_logaction("removed %s (%s)", info->name, info->version);
}
-
- /* cache needs to be rebuilt */
- db_free_pkgcache(db);
}
/* run ldconfig if it exists */
diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c
index 34e8acae..f6de47d3 100644
--- a/lib/libalpm/sync.c
+++ b/lib/libalpm/sync.c
@@ -65,7 +65,9 @@ void sync_free(pmsyncpkg_t *sync)
{
if(sync) {
if(sync->type == PM_SYNC_TYPE_REPLACE) {
- FREELISTPTR(sync->data);
+ FREELISTPKGS(sync->data);
+ } else {
+ FREEPKG(sync->data);
}
free(sync);
}
@@ -471,6 +473,7 @@ int sync_commit(pmtrans_t *trans, pmdb_t *db_local)
PMList *i;
PMList *data;
pmtrans_t *tr;
+ int replaces = 0;
ASSERT(db_local != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
@@ -493,9 +496,10 @@ int sync_commit(pmtrans_t *trans, pmdb_t *db_local)
if(trans_addtarget(tr, pkg->name)) {
goto error;
}
+ replaces++;
}
}
- if(tr->packages) {
+ if(replaces) {
_alpm_log(PM_LOG_FLOW1, "removing to-be-replaced packages");
if(trans_prepare(tr, &data) == -1) {
_alpm_log(PM_LOG_ERROR, "could not prepare transaction");
@@ -547,42 +551,43 @@ int sync_commit(pmtrans_t *trans, pmdb_t *db_local)
trans_free(tr);
/* propagate replaced packages' requiredby fields to their new owners */
- _alpm_log(PM_LOG_FLOW1, "updating database for replaced packages dependencies");
- for(i = trans->packages; i; i = i->next) {
- pmsyncpkg_t *sync = i->data;
- if(sync->type == PM_SYNC_TYPE_REPLACE) {
- PMList *j;
- pmpkg_t *new = db_get_pkgfromcache(db_local, sync->pkg->name);
- for(j = sync->data; j; j = j->next) {
- PMList *k;
- pmpkg_t *old = j->data;
- /* merge lists */
- for(k = old->requiredby; k; k = k->next) {
- if(!pm_list_is_strin(k->data, new->requiredby)) {
- /* replace old's name with new's name in the requiredby's dependency list */
- PMList *m;
- pmpkg_t *depender = db_get_pkgfromcache(db_local, k->data);
- for(m = depender->depends; m; m = m->next) {
- if(!strcmp(m->data, old->name)) {
- FREE(m->data);
- m->data = strdup(new->name);
+ if(replaces) {
+ _alpm_log(PM_LOG_FLOW1, "updating database for replaced packages dependencies");
+ for(i = trans->packages; i; i = i->next) {
+ pmsyncpkg_t *sync = i->data;
+ if(sync->type == PM_SYNC_TYPE_REPLACE) {
+ PMList *j;
+ pmpkg_t *new = db_get_pkgfromcache(db_local, sync->pkg->name);
+ for(j = sync->data; j; j = j->next) {
+ PMList *k;
+ pmpkg_t *old = j->data;
+ /* merge lists */
+ for(k = old->requiredby; k; k = k->next) {
+ if(!pm_list_is_strin(k->data, new->requiredby)) {
+ /* replace old's name with new's name in the requiredby's dependency list */
+ PMList *m;
+ pmpkg_t *depender = db_get_pkgfromcache(db_local, k->data);
+ for(m = depender->depends; m; m = m->next) {
+ if(!strcmp(m->data, old->name)) {
+ FREE(m->data);
+ m->data = strdup(new->name);
+ }
+ }
+ if(db_write(db_local, depender, INFRQ_DEPENDS) == -1) {
+ _alpm_log(PM_LOG_ERROR, "could not update 'requiredby' database entry %s/%s-%s", db_local->treename, new->name, new->version);
}
+ /* add the new requiredby */
+ new->requiredby = pm_list_add(new->requiredby, strdup(k->data));
}
- db_write(db_local, depender, INFRQ_DEPENDS);
-
- /* add the new requiredby */
- new->requiredby = pm_list_add(new->requiredby, strdup(k->data));
}
}
+ if(db_write(db_local, new, INFRQ_DEPENDS) == -1) {
+ _alpm_log(PM_LOG_ERROR, "could not update new database entry %s/%s-%s", db_local->treename, new->name, new->version);
+ }
}
- db_write(db_local, new, INFRQ_DEPENDS);
- FREEPKG(new);
}
}
- /* cache needs to be rebuilt */
- db_free_pkgcache(db_local);
-
return(0);
error: