summaryrefslogtreecommitdiffstats
path: root/usr.sbin/pkg_install
diff options
context:
space:
mode:
authorkrion <krion@FreeBSD.org>2007-11-02 20:18:47 +0000
committerkrion <krion@FreeBSD.org>2007-11-02 20:18:47 +0000
commit9dbf4a643df1b1167ae8a157205718cde1f7c0b5 (patch)
treeab96a97156ff5035b1dc4ffe35b8415342415cda /usr.sbin/pkg_install
parent0bf0ae3b24810072f6313df54fe1bf99d2feb341 (diff)
downloadFreeBSD-src-9dbf4a643df1b1167ae8a157205718cde1f7c0b5.zip
FreeBSD-src-9dbf4a643df1b1167ae8a157205718cde1f7c0b5.tar.gz
Momoize the results of isinstalledpkg()
PR: bin/116452 Submitted by: wollmann MFC after: 7 days
Diffstat (limited to 'usr.sbin/pkg_install')
-rw-r--r--usr.sbin/pkg_install/lib/match.c66
1 files changed, 56 insertions, 10 deletions
diff --git a/usr.sbin/pkg_install/lib/match.c b/usr.sbin/pkg_install/lib/match.c
index 2de0dc7..1dba77c 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;
- snprintf(buf, sizeof(buf), "%s/%s", LOG_DIR, name);
- if (!isdir(buf) || access(buf, R_OK) == FAIL)
- return 0;
-
- snprintf(buf2, sizeof(buf2), "%s/%s", buf, CONTENTS_FNAME);
- if (!isfile(buf2) || access(buf2, R_OK) == FAIL)
- return -1;
+ 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;
+ }
- return 1;
+ free(buf);
+ buf = strdup(name);
+ if (buf == NULL)
+ goto errout;
+ free(buf2);
+ buf2 = NULL;
+
+ 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;
+
+errout:
+ if (buf != NULL)
+ free(buf);
+ if (buf2 != NULL)
+ free(buf2);
+ return -1;
}
/*
OpenPOWER on IntegriCloud