summaryrefslogtreecommitdiffstats
path: root/lib/libalpm/be_sync.c
diff options
context:
space:
mode:
authorDan McGee <dan@archlinux.org>2010-12-15 05:26:23 +0100
committerDan McGee <dan@archlinux.org>2010-12-21 21:58:17 +0100
commitf2dff0860053f45c91e4ee301fda091a6b3d7361 (patch)
treea62d43b8041f172a67b1c0e0d2ca8336ea698fee /lib/libalpm/be_sync.c
parent126f50ab0b5ee3ed46c5a6ecae241e8af49b0fe2 (diff)
downloadpacman-f2dff0860053f45c91e4ee301fda091a6b3d7361.tar.gz
pacman-f2dff0860053f45c91e4ee301fda091a6b3d7361.tar.xz
Overhaul archive fgets function
The old function was written in a time before we relied on it for nearly every operation. Since then, we have switched to the archive backend and now fast parsing is a big deal. The former function made a per-character call to the libarchive archive_read_data() function, which resulted in some 21 million calls in a typical "load all sync dbs" operation. If we instead do some buffering of our own and read the blocks directly, and then find our newlines from there, we can cut out the multiple layers of overhead and go from archive to parsed data much quicker. Both users of the former function are switched over to the new signature, made easier by the macros now in place in the sync backend parsing code. Performance: for a `pacman -Su` (no upgrades available), _alpm_archive_fgets() goes from being 29% of the total time to 12% The time spent on the libarchive function being called dropped from 24% to 6%. This pushes _alpm_pkg_find back to the title of slowest low-level function. Signed-off-by: Dan McGee <dan@archlinux.org>
Diffstat (limited to 'lib/libalpm/be_sync.c')
-rw-r--r--lib/libalpm/be_sync.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c
index 137fc1b2..d0f98c20 100644
--- a/lib/libalpm/be_sync.c
+++ b/lib/libalpm/be_sync.c
@@ -219,8 +219,8 @@ static int sync_db_populate(pmdb_t *db)
}
#define READ_NEXT(s) do { \
- if(_alpm_archive_fgets(s, sizeof(s), archive) == NULL) goto error; \
- _alpm_strtrim(s); \
+ if(_alpm_archive_fgets(archive, &buf) != ARCHIVE_OK) goto error; \
+ s = _alpm_strtrim(buf.line); \
} while(0)
#define READ_AND_STORE(f) do { \
@@ -238,10 +238,10 @@ static int sync_db_populate(pmdb_t *db)
static int sync_db_read(pmdb_t *db, struct archive *archive, struct archive_entry *entry)
{
- char line[1024];
const char *entryname = NULL;
char *filename, *pkgname, *p, *q;
pmpkg_t *pkg;
+ struct archive_read_buffer buf;
ALPM_LOG_FUNC;
@@ -260,6 +260,10 @@ static int sync_db_read(pmdb_t *db, struct archive *archive, struct archive_entr
_alpm_log(PM_LOG_FUNCTION, "loading package data from archive entry %s\n",
entryname);
+ memset(&buf, 0, sizeof(buf));
+ /* 512K for a line length seems reasonable */
+ buf.max_line_size = 512 * 1024;
+
/* get package and db file names */
STRDUP(pkgname, entryname, RET_ERR(PM_ERR_MEMORY, -1));
p = pkgname + strlen(pkgname);
@@ -279,8 +283,9 @@ static int sync_db_read(pmdb_t *db, struct archive *archive, struct archive_entr
if(strcmp(filename, "desc") == 0 || strcmp(filename, "depends") == 0
|| strcmp(filename, "deltas") == 0) {
- while(_alpm_archive_fgets(line, sizeof(line), archive) != NULL) {
- _alpm_strtrim(line);
+ while(_alpm_archive_fgets(archive, &buf) == ARCHIVE_OK) {
+ char *line = _alpm_strtrim(buf.line);
+
if(strcmp(line, "%NAME%") == 0) {
READ_NEXT(line);
if(strcmp(line, pkg->name) != 0) {