diff options
| author | Kirill Ponomarev <krion@FreeBSD.org> | 2007-11-02 20:18:47 +0000 |
|---|---|---|
| committer | Kirill Ponomarev <krion@FreeBSD.org> | 2007-11-02 20:18:47 +0000 |
| commit | 2704bd0e1319b66dfa98d0d528496bc4f7817bb2 (patch) | |
| tree | ab96a97156ff5035b1dc4ffe35b8415342415cda /usr.sbin/pkg_install | |
| parent | f4bb4fc8f3535e283547d8240a41593e3fa5e091 (diff) | |
Notes
Diffstat (limited to 'usr.sbin/pkg_install')
| -rw-r--r-- | usr.sbin/pkg_install/lib/match.c | 64 |
1 files changed, 55 insertions, 9 deletions
diff --git a/usr.sbin/pkg_install/lib/match.c b/usr.sbin/pkg_install/lib/match.c index 2de0dc72476e4..1dba77ccc5235 100644 --- a/usr.sbin/pkg_install/lib/match.c +++ b/usr.sbin/pkg_install/lib/match.c @@ -307,6 +307,17 @@ matchbyorigin(const char *origin, int *retval) } /* + * Small linked list to memoize results of isinstalledpkg(). A hash table + * would be faster but for n ~= 1000 may be overkill. + */ +struct iip_memo { + LIST_ENTRY(iip_memo) iip_link; + char *iip_name; + int iip_result; +}; +LIST_HEAD(, iip_memo) iip_memo = LIST_HEAD_INITIALIZER(iip_memo); + +/* * * Return 1 if the specified package is installed, * 0 if not, and -1 if an error occured. @@ -314,18 +325,53 @@ matchbyorigin(const char *origin, int *retval) int isinstalledpkg(const char *name) { - char buf[FILENAME_MAX]; - char buf2[FILENAME_MAX]; + int result; + char *buf, *buf2; + struct iip_memo *memo; + + LIST_FOREACH(memo, &iip_memo, iip_link) { + if (strcmp(memo->iip_name, name) == 0) + return memo->iip_result; + } + + buf2 = NULL; + asprintf(&buf, "%s/%s", LOG_DIR, name); + if (buf == NULL) + goto errout; + if (!isdir(buf) || access(buf, R_OK) == FAIL) { + result = 0; + } else { + asprintf(&buf2, "%s/%s", buf, CONTENTS_FNAME); + if (buf2 == NULL) + goto errout; + + if (!isfile(buf2) || access(buf2, R_OK) == FAIL) + result = -1; + else + result = 1; + } - snprintf(buf, sizeof(buf), "%s/%s", LOG_DIR, name); - if (!isdir(buf) || access(buf, R_OK) == FAIL) - return 0; + free(buf); + buf = strdup(name); + if (buf == NULL) + goto errout; + free(buf2); + buf2 = NULL; - snprintf(buf2, sizeof(buf2), "%s/%s", buf, CONTENTS_FNAME); - if (!isfile(buf2) || access(buf2, R_OK) == FAIL) - return -1; + memo = malloc(sizeof *memo); + if (memo == NULL) + goto errout; + memo->iip_name = buf; + memo->iip_result = result; + LIST_INSERT_HEAD(&iip_memo, memo, iip_link); + return result; - return 1; +errout: + if (buf != NULL) + free(buf); + if (buf2 != NULL) + free(buf2); + return -1; } /* |
