rework the cache handling to avoid as much as possible calls to db_scan()

This commit is contained in:
Aurelien Foret 2005-04-23 17:18:31 +00:00
parent e56980597b
commit e2b474b130
7 changed files with 150 additions and 62 deletions

View file

@ -273,11 +273,13 @@ int add_commit(pmtrans_t *trans, pmdb_t *db)
/* we'll need the full record for backup checks later */ /* we'll need the full record for backup checks later */
oldpkg = pkg_new(); oldpkg = pkg_new();
if(oldpkg) {
STRNCPY(oldpkg->name, info->name, PKG_NAME_LEN); STRNCPY(oldpkg->name, info->name, PKG_NAME_LEN);
STRNCPY(oldpkg->version, info->version, PKG_VERSION_LEN); STRNCPY(oldpkg->version, info->version, PKG_VERSION_LEN);
oldpkg->backup = _alpm_list_strdup(info->backup); oldpkg->backup = _alpm_list_strdup(info->backup);
/* ORE /* ORE
oldpkg->reason = info->reason;*/ oldpkg->reason = info->reason;*/
}
/* pre_upgrade scriptlet */ /* pre_upgrade scriptlet */
if(info->scriptlet) { if(info->scriptlet) {
@ -364,16 +366,15 @@ int add_commit(pmtrans_t *trans, pmdb_t *db)
}*/ }*/
/* make an install date (in UTC) */ /* make an install date (in UTC) */
STRNCPY(info->installdate, asctime(gmtime(&t)), sizeof(info->installdate)); 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)) { 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_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); alpm_logaction(NULL, "error updating database for %s-%s!", info->name, info->version);
RET_ERR(PM_ERR_DB_WRITE, -1); RET_ERR(PM_ERR_DB_WRITE, -1);
} }
/* ORE if(db_add_pkgincache(db, info) == -1) {
in case of an installation, then add info in the pkgcache _alpm_log(PM_LOG_ERROR, "could not add entry %s in cache", info->name);
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) */
/* update dependency packages' REQUIREDBY fields */ /* update dependency packages' REQUIREDBY fields */
_alpm_log(PM_LOG_FLOW2, "updating 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 /* ORE
same thing here: we should browse the cache instead of using db_scan */ 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) { if(depinfo == NULL) {
/* look for a provides package */ /* look for a provides package */
/* ORE /* ORE
@ -399,7 +400,7 @@ int add_commit(pmtrans_t *trans, pmdb_t *db)
* the first one. * the first one.
*/ */
/* use 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); FREELISTPTR(provides);
if(depinfo == NULL) { if(depinfo == NULL) {
/* wtf */ /* wtf */
@ -409,15 +410,11 @@ int add_commit(pmtrans_t *trans, pmdb_t *db)
continue; 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)); depinfo->requiredby = pm_list_add(depinfo->requiredby, strdup(info->name));
_alpm_log(PM_LOG_DEBUG, "updating 'requiredby' field for package %s", depinfo->name); _alpm_log(PM_LOG_DEBUG, "updating 'requiredby' field for package %s", depinfo->name);
if(db_write(db, depinfo, INFRQ_DEPENDS)) { 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); _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 */ /* Extract the .tar.gz package */
@ -640,13 +637,6 @@ int add_commit(pmtrans_t *trans, pmdb_t *db)
} }
FREEPKG(oldpkg); 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 */ /* run ldconfig if it exists */

View file

@ -64,7 +64,7 @@ int db_load_pkgcache(pmdb_t *db)
void db_free_pkgcache(pmdb_t *db) void db_free_pkgcache(pmdb_t *db)
{ {
if(db == NULL || db->pkgcache == NULL) { if(db == NULL) {
return; return;
} }
@ -88,6 +88,57 @@ PMList *db_get_pkgcache(pmdb_t *db)
return(db->pkgcache); 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) pmpkg_t *db_get_pkgfromcache(pmdb_t *db, char *target)
{ {
PMList *i; PMList *i;
@ -158,7 +209,7 @@ void db_free_grpcache(pmdb_t *db)
{ {
PMList *lg; PMList *lg;
if(db == NULL || db->grpcache == NULL) { if(db == NULL) {
return; return;
} }

View file

@ -29,6 +29,8 @@
/* packages */ /* packages */
int db_load_pkgcache(pmdb_t *db); int db_load_pkgcache(pmdb_t *db);
void db_free_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); PMList *db_get_pkgcache(pmdb_t *db);
pmpkg_t *db_get_pkgfromcache(pmdb_t *db, char *target); pmpkg_t *db_get_pkgfromcache(pmdb_t *db, char *target);
/* groups */ /* groups */

View file

@ -71,6 +71,45 @@ pmpkg_t *pkg_new()
return(pkg); 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) void pkg_free(pmpkg_t *pkg)
{ {
if(pkg == NULL) { if(pkg == NULL) {

View file

@ -80,6 +80,7 @@ typedef struct __pmpkg_t {
} while(0) } while(0)
pmpkg_t* pkg_new(); pmpkg_t* pkg_new();
pmpkg_t *pkg_dup(pmpkg_t *pkg);
void pkg_free(pmpkg_t *pkg); void pkg_free(pmpkg_t *pkg);
pmpkg_t *pkg_load(char *pkgfile); pmpkg_t *pkg_load(char *pkgfile);
int pkg_cmp(const void *p1, const void *p2); int pkg_cmp(const void *p1, const void *p2);

View file

@ -211,8 +211,12 @@ int remove_commit(pmtrans_t *trans, pmdb_t *db)
/* remove the package from the database */ /* remove the package from the database */
_alpm_log(PM_LOG_FLOW1, "updating 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) { 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 */ /* update dependency packages' REQUIREDBY fields */
@ -226,7 +230,7 @@ int remove_commit(pmtrans_t *trans, pmdb_t *db)
continue; continue;
} }
depinfo = db_scan(db, depend.name, INFRQ_DESC|INFRQ_DEPENDS); depinfo = db_get_pkgfromcache(db, depend.name);
if(depinfo == NULL) { if(depinfo == NULL) {
/* look for a provides package */ /* look for a provides package */
PMList *provides = _alpm_db_whatprovides(db, depend.name); PMList *provides = _alpm_db_whatprovides(db, depend.name);
@ -235,7 +239,7 @@ int remove_commit(pmtrans_t *trans, pmdb_t *db)
* the first one. * the first one.
*/ */
/* use 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); FREELISTPTR(provides);
if(depinfo == NULL) { if(depinfo == NULL) {
/* wtf */ /* wtf */
@ -256,16 +260,12 @@ int remove_commit(pmtrans_t *trans, pmdb_t *db)
if(db_write(db, depinfo, INFRQ_DEPENDS)) { 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); _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) { if(trans->type != PM_TRANS_TYPE_UPGRADE) {
TRANS_CB(trans, PM_TRANS_EVT_REMOVE_DONE, info, NULL); TRANS_CB(trans, PM_TRANS_EVT_REMOVE_DONE, info, NULL);
alpm_logaction("removed %s (%s)", info->name, info->version); alpm_logaction("removed %s (%s)", info->name, info->version);
} }
/* cache needs to be rebuilt */
db_free_pkgcache(db);
} }
/* run ldconfig if it exists */ /* run ldconfig if it exists */

View file

@ -65,7 +65,9 @@ void sync_free(pmsyncpkg_t *sync)
{ {
if(sync) { if(sync) {
if(sync->type == PM_SYNC_TYPE_REPLACE) { if(sync->type == PM_SYNC_TYPE_REPLACE) {
FREELISTPTR(sync->data); FREELISTPKGS(sync->data);
} else {
FREEPKG(sync->data);
} }
free(sync); free(sync);
} }
@ -471,6 +473,7 @@ int sync_commit(pmtrans_t *trans, pmdb_t *db_local)
PMList *i; PMList *i;
PMList *data; PMList *data;
pmtrans_t *tr; pmtrans_t *tr;
int replaces = 0;
ASSERT(db_local != NULL, RET_ERR(PM_ERR_DB_NULL, -1)); ASSERT(db_local != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_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)) { if(trans_addtarget(tr, pkg->name)) {
goto error; goto error;
} }
replaces++;
} }
} }
if(tr->packages) { if(replaces) {
_alpm_log(PM_LOG_FLOW1, "removing to-be-replaced packages"); _alpm_log(PM_LOG_FLOW1, "removing to-be-replaced packages");
if(trans_prepare(tr, &data) == -1) { if(trans_prepare(tr, &data) == -1) {
_alpm_log(PM_LOG_ERROR, "could not prepare transaction"); _alpm_log(PM_LOG_ERROR, "could not prepare transaction");
@ -547,6 +551,7 @@ int sync_commit(pmtrans_t *trans, pmdb_t *db_local)
trans_free(tr); trans_free(tr);
/* propagate replaced packages' requiredby fields to their new owners */ /* propagate replaced packages' requiredby fields to their new owners */
if(replaces) {
_alpm_log(PM_LOG_FLOW1, "updating database for replaced packages dependencies"); _alpm_log(PM_LOG_FLOW1, "updating database for replaced packages dependencies");
for(i = trans->packages; i; i = i->next) { for(i = trans->packages; i; i = i->next) {
pmsyncpkg_t *sync = i->data; pmsyncpkg_t *sync = i->data;
@ -568,20 +573,20 @@ int sync_commit(pmtrans_t *trans, pmdb_t *db_local)
m->data = strdup(new->name); m->data = strdup(new->name);
} }
} }
db_write(db_local, depender, INFRQ_DEPENDS); 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 */ /* add the new requiredby */
new->requiredby = pm_list_add(new->requiredby, strdup(k->data)); new->requiredby = pm_list_add(new->requiredby, strdup(k->data));
} }
} }
} }
db_write(db_local, new, INFRQ_DEPENDS); if(db_write(db_local, new, INFRQ_DEPENDS) == -1) {
FREEPKG(new); _alpm_log(PM_LOG_ERROR, "could not update new database entry %s/%s-%s", db_local->treename, new->name, new->version);
}
}
} }
} }
/* cache needs to be rebuilt */
db_free_pkgcache(db_local);
return(0); return(0);