Fix rewinddir regression by cleaning up db_scan

Commit 0460038447 caused a regression when
rereading the pkgcache after updating the on-disk databases. A rewinddir
call was errantly removed.

Instead of replacing the call to rewindir, clean up this whole mess.
db_scan is used only once and with target == NULL so there was actually half
the code of db_scan which was unused. This is gone now and replaced by a
single new db_populate function.

Dan: add_sorted ended up being 3x slower than one msort at the end, so I
changed back to that. I also made one pointer variable const and merged this
whole patch with my original fix for the rewinddir issue.

Signed-off-by: Xavier Chantry <shiningxc@gmail.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
This commit is contained in:
Xavier Chantry 2008-05-12 18:56:14 -05:00 committed by Dan McGee
parent ae5ef3b90f
commit f671147282
3 changed files with 37 additions and 91 deletions

View File

@ -177,8 +177,8 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db)
for(lp = _alpm_db_get_pkgcache(db); lp; lp = lp->next) { for(lp = _alpm_db_get_pkgcache(db); lp; lp = lp->next) {
pmpkg_t *pkg = lp->data; pmpkg_t *pkg = lp->data;
if(pkg && _alpm_db_remove(db, pkg) == -1) { if(pkg && _alpm_db_remove(db, pkg) == -1) {
_alpm_log(PM_LOG_ERROR, _("could not remove database entry %s%s\n"), db->treename, _alpm_log(PM_LOG_ERROR, _("could not remove database entry %s%s\n"),
alpm_pkg_get_name(pkg)); db->treename, pkg->name);
RET_ERR(PM_ERR_DB_REMOVE, -1); RET_ERR(PM_ERR_DB_REMOVE, -1);
} }
} }
@ -273,104 +273,60 @@ static int splitname(const char *target, pmpkg_t *pkg)
return(0); return(0);
} }
pmpkg_t *_alpm_db_scan(pmdb_t *db, const char *target) int _alpm_db_populate(pmdb_t *db)
{ {
int count = 0;
struct dirent *ent = NULL; struct dirent *ent = NULL;
struct stat sbuf; struct stat sbuf;
char path[PATH_MAX]; char path[PATH_MAX];
char *ptr = NULL;
int found = 0;
pmpkg_t *pkg = NULL;
ALPM_LOG_FUNC; ALPM_LOG_FUNC;
if(db == NULL) { ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
RET_ERR(PM_ERR_DB_NULL, NULL);
}
/* We loop here until we read a valid package. When an iteration of this loop rewinddir(db->handle);
* fails, it means alpm_db_read failed to read a valid package, so we'll read while((ent = readdir(db->handle)) != NULL) {
* the next so as not to abort whole-db operations early const char *name = ent->d_name;
*/ pmpkg_t *pkg;
while(!pkg) {
if(target != NULL) {
/* search for a specific package (by name only) */
rewinddir(db->handle);
while(!found && (ent = readdir(db->handle)) != NULL) {
char *name;
if(strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) { if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0) {
continue; continue;
} }
/* stat the entry, make sure it's a directory */ /* stat the entry, make sure it's a directory */
snprintf(path, PATH_MAX, "%s/%s", db->path, ent->d_name); snprintf(path, PATH_MAX, "%s/%s", db->path, name);
if(stat(path, &sbuf) || !S_ISDIR(sbuf.st_mode)) { if(stat(path, &sbuf) != 0 || !S_ISDIR(sbuf.st_mode)) {
continue; continue;
}
STRDUP(name, ent->d_name, return(NULL));
/* truncate the string at the second-to-last hyphen, */
/* which will give us the package name */
if((ptr = rindex(name, '-'))) {
*ptr = '\0';
}
if((ptr = rindex(name, '-'))) {
*ptr = '\0';
}
if(strcmp(name, target) == 0) {
found = 1;
}
FREE(name);
}
if(!found) {
return(NULL);
}
} else { /* target == NULL, full scan */
int isdir = 0;
while(!isdir) {
ent = readdir(db->handle);
if(ent == NULL) {
return(NULL);
}
if(strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) {
isdir = 0;
continue;
}
/* stat the entry, make sure it's a directory */
snprintf(path, PATH_MAX, "%s/%s", db->path, ent->d_name);
if(!stat(path, &sbuf) && S_ISDIR(sbuf.st_mode)) {
isdir = 1;
}
}
} }
pkg = _alpm_pkg_new(NULL, NULL); pkg = _alpm_pkg_new(NULL, NULL);
if(pkg == NULL) { if(pkg == NULL) {
_alpm_log(PM_LOG_DEBUG, "db scan could not find package: %s\n", target); return(-1);
return(NULL);
} }
/* split the db entry name */ /* split the db entry name */
if(splitname(ent->d_name, pkg) != 0) { if(splitname(name, pkg) != 0) {
_alpm_log(PM_LOG_ERROR, _("invalid name for database entry '%s'\n"), _alpm_log(PM_LOG_ERROR, _("invalid name for database entry '%s'\n"),
ent->d_name); name);
alpm_pkg_free(pkg); _alpm_pkg_free(pkg);
pkg = NULL;
continue; continue;
} }
/* explicitly read with only 'BASE' data, accessors will handle the rest */ /* explicitly read with only 'BASE' data, accessors will handle the rest */
if(_alpm_db_read(db, pkg, INFRQ_BASE) == -1) { if(_alpm_db_read(db, pkg, INFRQ_BASE) == -1) {
/* TODO removed corrupt entry from the FS here */ _alpm_log(PM_LOG_ERROR, _("corrupted database entry '%s'\n"), name);
_alpm_pkg_free(pkg); _alpm_pkg_free(pkg);
} else { continue;
pkg->origin = PKG_FROM_CACHE;
pkg->origin_data.db = db;
} }
pkg->origin = PKG_FROM_CACHE;
pkg->origin_data.db = db;
/* add to the collection */
_alpm_log(PM_LOG_FUNCTION, "adding '%s' to package cache for db '%s'\n",
pkg->name, db->treename);
db->pkgcache = alpm_list_add(db->pkgcache, pkg);
count++;
} }
return(pkg); db->pkgcache = alpm_list_msort(db->pkgcache, count, _alpm_pkg_cmp);
return(count);
} }
int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)

View File

@ -40,31 +40,21 @@
*/ */
int _alpm_db_load_pkgcache(pmdb_t *db) int _alpm_db_load_pkgcache(pmdb_t *db)
{ {
pmpkg_t *info;
int count = 0;
ALPM_LOG_FUNC; ALPM_LOG_FUNC;
if(db == NULL) { if(db == NULL) {
return(-1); return(-1);
} }
_alpm_db_free_pkgcache(db); _alpm_db_free_pkgcache(db);
_alpm_log(PM_LOG_DEBUG, "loading package cache for repository '%s'\n", _alpm_log(PM_LOG_DEBUG, "loading package cache for repository '%s'\n",
db->treename); db->treename);
if(_alpm_db_populate(db) == -1) {
while((info = _alpm_db_scan(db, NULL)) != NULL) { _alpm_log(PM_LOG_DEBUG,
_alpm_log(PM_LOG_FUNCTION, "adding '%s' to package cache for db '%s'\n", "failed to load package cache for repository '%s'\n", db->treename);
alpm_pkg_get_name(info), db->treename); return(-1);
info->origin = PKG_FROM_CACHE;
info->origin_data.db = db;
/* add to the collection */
db->pkgcache = alpm_list_add(db->pkgcache, info);
count++;
} }
db->pkgcache = alpm_list_msort(db->pkgcache, count, _alpm_pkg_cmp);
return(0); return(0);
} }

View File

@ -58,7 +58,7 @@ pmdb_t *_alpm_db_register_sync(const char *treename);
/* be.c, backend specific calls */ /* be.c, backend specific calls */
int _alpm_db_open(pmdb_t *db); int _alpm_db_open(pmdb_t *db);
void _alpm_db_close(pmdb_t *db); void _alpm_db_close(pmdb_t *db);
pmpkg_t *_alpm_db_scan(pmdb_t *db, const char *target); int _alpm_db_populate(pmdb_t *db);
int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq); int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq);
int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq); int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq);
int _alpm_db_remove(pmdb_t *db, pmpkg_t *info); int _alpm_db_remove(pmdb_t *db, pmpkg_t *info);