From e2b474b1309594c610a2cf25f35b349575d88223 Mon Sep 17 00:00:00 2001 From: Aurelien Foret Date: Sat, 23 Apr 2005 17:18:31 +0000 Subject: rework the cache handling to avoid as much as possible calls to db_scan() --- lib/libalpm/add.c | 36 +++++++++++----------------- lib/libalpm/cache.c | 55 +++++++++++++++++++++++++++++++++++++++++-- lib/libalpm/cache.h | 2 ++ lib/libalpm/package.c | 39 +++++++++++++++++++++++++++++++ lib/libalpm/package.h | 1 + lib/libalpm/remove.c | 14 +++++------ lib/libalpm/sync.c | 65 +++++++++++++++++++++++++++------------------------ 7 files changed, 150 insertions(+), 62 deletions(-) (limited to 'lib/libalpm') 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: -- cgit v1.2.3-70-g09d2