rework the cache handling to avoid as much as possible calls to db_scan()
This commit is contained in:
parent
e56980597b
commit
e2b474b130
7 changed files with 150 additions and 62 deletions
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Add table
Reference in a new issue