summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan McGee <dan@archlinux.org>2011-12-30 12:17:52 -0600
committerDan McGee <dan@archlinux.org>2012-01-02 12:55:55 -0600
commit819c28bf8c666a61ef3b0a016dcbd6962ecaf4e4 (patch)
tree7f6f9ba221cf7aa40daad40063a9110ddaecc20f
parent627cf6bca88c241d7e0d5563db46f87f64792653 (diff)
downloadpacman-819c28bf8c666a61ef3b0a016dcbd6962ecaf4e4.tar.xz
Only compile delta regex once
This reduces the number of regcomp() calls when parsing delta entries in the database from once per entry to once for the entire context handle by storing the compiled regex data on the handle itself. Just as we do with the cURL handle, we initialize it the first time it is needed and free it when releasing the handle. A few other small tweaks to the parsing function also take place, including using the stack to store the transient and short file size string while parsing it. When parsing a sync database with 1378 delta entries, this reduces the time of a `pacman -Sl deltas` operation by 50% from 0.22s to 0.12s. Signed-off-by: Dan McGee <dan@archlinux.org>
-rw-r--r--lib/libalpm/be_sync.c3
-rw-r--r--lib/libalpm/delta.c33
-rw-r--r--lib/libalpm/delta.h2
-rw-r--r--lib/libalpm/handle.c3
-rw-r--r--lib/libalpm/handle.h5
5 files changed, 30 insertions, 16 deletions
diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c
index abc4a997..da2260e8 100644
--- a/lib/libalpm/be_sync.c
+++ b/lib/libalpm/be_sync.c
@@ -598,7 +598,8 @@ static int sync_db_read(alpm_db_t *db, struct archive *archive,
while(1) {
READ_NEXT();
if(strlen(line) == 0) break;
- pkg->deltas = alpm_list_add(pkg->deltas, _alpm_delta_parse(line));
+ pkg->deltas = alpm_list_add(pkg->deltas,
+ _alpm_delta_parse(db->handle, line));
}
}
}
diff --git a/lib/libalpm/delta.c b/lib/libalpm/delta.c
index 165cdef4..726f03c0 100644
--- a/lib/libalpm/delta.c
+++ b/lib/libalpm/delta.c
@@ -273,29 +273,32 @@ alpm_list_t SYMEXPORT *alpm_pkg_unused_deltas(alpm_pkg_t *pkg)
* This function assumes that the string is in the correct format.
* This format is as follows:
* $deltafile $deltamd5 $deltasize $oldfile $newfile
+ * @param handle the context handle
* @param line the string to parse
* @return A pointer to the new alpm_delta_t object
*/
-/* TODO this does not really belong here, but in a parsing lib */
-alpm_delta_t *_alpm_delta_parse(char *line)
+alpm_delta_t *_alpm_delta_parse(alpm_handle_t *handle, const char *line)
{
alpm_delta_t *delta;
- char *tmp;
const int num_matches = 6;
size_t len;
- regex_t reg;
regmatch_t pmatch[num_matches];
+ char filesize[32];
+
+ /* this is so we only have to compile the pattern once */
+ if(!handle->delta_regex_compiled) {
+ /* $deltafile $deltamd5 $deltasize $oldfile $newfile*/
+ regcomp(&handle->delta_regex,
+ "^([^[:space:]]+) ([[:xdigit:]]{32}) ([[:digit:]]+)"
+ " ([^[:space:]]+) ([^[:space:]]+)$",
+ REG_EXTENDED | REG_NEWLINE);
+ handle->delta_regex_compiled = 1;
+ }
- regcomp(&reg,
- "^([^[:space:]]*) ([[:xdigit:]]{32}) ([[:digit:]]*)"
- " ([^[:space:]]*) ([^[:space:]]*)$",
- REG_EXTENDED | REG_NEWLINE);
- if(regexec(&reg, line, num_matches, pmatch, 0) != 0) {
+ if(regexec(&handle->delta_regex, line, num_matches, pmatch, 0) != 0) {
/* delta line is invalid, return NULL */
- regfree(&reg);
return NULL;
}
- regfree(&reg);
CALLOC(delta, 1, sizeof(alpm_delta_t), return NULL);
@@ -307,9 +310,11 @@ alpm_delta_t *_alpm_delta_parse(char *line)
STRNDUP(delta->delta_md5, &line[pmatch[2].rm_so], len, return NULL);
len = pmatch[3].rm_eo - pmatch[3].rm_so;
- STRNDUP(tmp, &line[pmatch[3].rm_so], len, return NULL);
- delta->delta_size = _alpm_strtoofft(tmp);
- free(tmp);
+ if(len < sizeof(filesize)) {
+ strncpy(filesize, &line[pmatch[3].rm_so], len);
+ filesize[len] = '\0';
+ delta->delta_size = _alpm_strtoofft(filesize);
+ }
len = pmatch[4].rm_eo - pmatch[4].rm_so;
STRNDUP(delta->from, &line[pmatch[4].rm_so], len, return NULL);
diff --git a/lib/libalpm/delta.h b/lib/libalpm/delta.h
index 42353f5f..1173ddfe 100644
--- a/lib/libalpm/delta.h
+++ b/lib/libalpm/delta.h
@@ -24,7 +24,7 @@
#include "alpm.h"
-alpm_delta_t *_alpm_delta_parse(char *line);
+alpm_delta_t *_alpm_delta_parse(alpm_handle_t *handle, const char *line);
void _alpm_delta_free(alpm_delta_t *delta);
alpm_delta_t *_alpm_delta_dup(const alpm_delta_t *delta);
off_t _alpm_shortest_delta_path(alpm_handle_t *handle, alpm_list_t *deltas,
diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c
index 6518b7d5..8e2e3c73 100644
--- a/lib/libalpm/handle.c
+++ b/lib/libalpm/handle.c
@@ -34,6 +34,7 @@
#include "alpm_list.h"
#include "util.h"
#include "log.h"
+#include "delta.h"
#include "trans.h"
#include "alpm.h"
@@ -67,6 +68,8 @@ void _alpm_handle_free(alpm_handle_t *handle)
curl_easy_cleanup(handle->curl);
#endif
+ regfree(&handle->delta_regex);
+
/* free memory */
_alpm_trans_free(handle->trans);
FREE(handle->root);
diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h
index 1f147d6e..a64c5c9e 100644
--- a/lib/libalpm/handle.h
+++ b/lib/libalpm/handle.h
@@ -22,6 +22,7 @@
#include <stdio.h>
#include <sys/types.h>
+#include <regex.h>
#include "alpm_list.h"
#include "alpm.h"
@@ -94,6 +95,10 @@ struct __alpm_handle_t {
/* error code */
alpm_errno_t pm_errno;
+
+ /* for delta parsing efficiency */
+ int delta_regex_compiled;
+ regex_t delta_regex;
};
alpm_handle_t *_alpm_handle_new(void);