summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan McGee <dan@archlinux.org>2010-12-29 18:43:47 -0600
committerDan McGee <dan@archlinux.org>2010-12-29 18:43:47 -0600
commita7972625e3ef98348b8a0957217aa2991501a07b (patch)
tree7ecda6bfc27215c7298ade25a3bf8f02ee610481
parenta58083459b096e935693d94b9cb51a447b3a1abd (diff)
parent735a197fc29b6b85a64cae5a6fa95e1209552c3b (diff)
downloadpacman-a7972625e3ef98348b8a0957217aa2991501a07b.tar.xz
Merge branch 'depcmp-perf'
-rw-r--r--lib/libalpm/deps.c41
-rw-r--r--lib/libalpm/deps.h3
2 files changed, 29 insertions, 15 deletions
diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c
index 21578293..2ed9d30a 100644
--- a/lib/libalpm/deps.c
+++ b/lib/libalpm/deps.c
@@ -322,32 +322,41 @@ 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);
+ const char *pkgname = pkg->name;
+ const char *pkgversion = pkg->version;
int satisfy = 0;
/* check (pkg->name, pkg->version) */
- satisfy = (strcmp(pkgname, dep->name) == 0
- && dep_vercmp(pkgversion, dep->mod, dep->version));
+ if(pkg->name_hash && dep->name_hash
+ && pkg->name_hash != dep->name_hash) {
+ /* skip more expensive checks */
+ } else {
+ 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);
@@ -376,7 +385,8 @@ pmdepend_t *_alpm_splitdep(const char *depstring)
depend->mod = PM_DEP_MOD_LE;
*ptr = '\0';
ptr += 2;
- } else if((ptr = strstr(newstr, "="))) { /* Note: we must do =,<,> checks after <=, >= checks */
+ } else if((ptr = strstr(newstr, "="))) {
+ /* Note: we must do =,<,> checks after <=, >= checks */
depend->mod = PM_DEP_MOD_EQ;
*ptr = '\0';
ptr += 1;
@@ -392,6 +402,7 @@ pmdepend_t *_alpm_splitdep(const char *depstring)
/* no version specified - copy the name and return it */
depend->mod = PM_DEP_MOD_ANY;
STRDUP(depend->name, newstr, RET_ERR(PM_ERR_MEMORY, NULL));
+ depend->name_hash = _alpm_hash_sdbm(depend->name);
depend->version = NULL;
free(newstr);
return(depend);
@@ -400,6 +411,7 @@ pmdepend_t *_alpm_splitdep(const char *depstring)
/* if we get here, we have a version comparator, copy the right parts
* to the right places */
STRDUP(depend->name, newstr, RET_ERR(PM_ERR_MEMORY, NULL));
+ depend->name_hash = _alpm_hash_sdbm(depend->name);
STRDUP(depend->version, ptr, RET_ERR(PM_ERR_MEMORY, NULL));
free(newstr);
@@ -412,6 +424,7 @@ pmdepend_t *_alpm_dep_dup(const pmdepend_t *dep)
CALLOC(newdep, 1, sizeof(pmdepend_t), RET_ERR(PM_ERR_MEMORY, NULL));
STRDUP(newdep->name, dep->name, RET_ERR(PM_ERR_MEMORY, NULL));
+ newdep->name_hash = dep->name_hash;
STRDUP(newdep->version, dep->version, RET_ERR(PM_ERR_MEMORY, NULL));
newdep->mod = dep->mod;
diff --git a/lib/libalpm/deps.h b/lib/libalpm/deps.h
index 6fa763e1..b720b364 100644
--- a/lib/libalpm/deps.h
+++ b/lib/libalpm/deps.h
@@ -29,9 +29,10 @@
/* Dependency */
struct __pmdepend_t {
- pmdepmod_t mod;
char *name;
char *version;
+ long name_hash;
+ pmdepmod_t mod;
};
/* Missing dependency */