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 */
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 */

View file

@ -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;
}

View file

@ -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 */

View file

@ -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) {

View file

@ -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);

View file

@ -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 */

View file

@ -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: