summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan McGee <dan@archlinux.org>2010-12-20 19:58:15 -0600
committerDan McGee <dan@archlinux.org>2010-12-21 17:25:02 -0600
commit34a78d935ac44fc73becc8bba213cdf0268bb5e0 (patch)
tree255242ae96734bbf0ed4c914cf049c0ed076a462
parent126f50ab0b5ee3ed46c5a6ecae241e8af49b0fe2 (diff)
downloadpacman-34a78d935ac44fc73becc8bba213cdf0268bb5e0.tar.xz
Remove need for memory allocation in _alpm_depcmp
Noticed when tweaking testdb, when we run _alpm_depcmp in loops and call it seven million times, the strdup()/free() combo can add up. Remove the need for any string duplication by some pointer manipulation and use of strncmp instead of strcmp. Also kill the function logger and add an escape so we don't needlessly retrieve the list of provides. Signed-off-by: Dan McGee <dan@archlinux.org>
-rw-r--r--lib/libalpm/deps.c22
1 files changed, 13 insertions, 9 deletions
diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c
index 21578293..e37eb02e 100644
--- a/lib/libalpm/deps.c
+++ b/lib/libalpm/deps.c
@@ -322,9 +322,6 @@ static int dep_vercmp(const char *version1, pmdepmod_t mod,
int _alpm_depcmp(pmpkg_t *pkg, pmdepend_t *dep)
{
alpm_list_t *i;
-
- ALPM_LOG_FUNC;
-
const char *pkgname = alpm_pkg_get_name(pkg);
const char *pkgversion = alpm_pkg_get_version(pkg);
int satisfy = 0;
@@ -332,22 +329,29 @@ int _alpm_depcmp(pmpkg_t *pkg, pmdepend_t *dep)
/* check (pkg->name, pkg->version) */
satisfy = (strcmp(pkgname, dep->name) == 0
&& dep_vercmp(pkgversion, dep->mod, dep->version));
+ if(satisfy) {
+ return(satisfy);
+ }
/* check provisions, format : "name=version" */
for(i = alpm_pkg_get_provides(pkg); i && !satisfy; i = i->next) {
- char *provname = strdup(i->data);
- char *provver = strchr(provname, '=');
+ const char *provision = i->data;
+ const char *provver = strchr(provision, '=');
if(provver == NULL) { /* no provision version */
satisfy = (dep->mod == PM_DEP_MOD_ANY
- && strcmp(provname, dep->name) == 0);
+ && strcmp(provision, dep->name) == 0);
} else {
- *provver = '\0';
+ /* This is a bit tricker than the old code for performance reasons. To
+ * prevent the need to copy and duplicate strings, strncmp only the name
+ * portion if they are the same length, since there is a version and
+ * operator in play here. */
+ size_t namelen = provver - provision;
provver += 1;
- satisfy = (strcmp(provname, dep->name) == 0
+ satisfy = (strlen(dep->name) == namelen
+ && strncmp(provision, dep->name, namelen) == 0
&& dep_vercmp(provver, dep->mod, dep->version));
}
- free(provname);
}
return(satisfy);