aboutsummaryrefslogtreecommitdiff
path: root/libpkgconf/cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'libpkgconf/cache.c')
-rw-r--r--libpkgconf/cache.c136
1 files changed, 136 insertions, 0 deletions
diff --git a/libpkgconf/cache.c b/libpkgconf/cache.c
new file mode 100644
index 0000000..986eba5
--- /dev/null
+++ b/libpkgconf/cache.c
@@ -0,0 +1,136 @@
+/*
+ * cache.c
+ * package object cache
+ *
+ * Copyright (c) 2013 pkgconf authors (see AUTHORS).
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * This software is provided 'as is' and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising
+ * from the use of this software.
+ */
+
+#include <libpkgconf/libpkgconf.h>
+
+/*
+ * !doc
+ *
+ * libpkgconf `cache` module
+ * =========================
+ *
+ * The libpkgconf `cache` module manages a package/module object cache, allowing it to
+ * avoid loading duplicate copies of a package/module.
+ *
+ * A cache is tied to a specific pkgconf client object, so package objects should not
+ * be shared across threads.
+ */
+
+/*
+ * !doc
+ *
+ * .. c:function:: pkgconf_pkg_t *pkgconf_cache_lookup(const pkgconf_client_t *client, const char *id)
+ *
+ * Looks up a package in the cache given an `id` atom,
+ * such as ``gtk+-3.0`` and returns the already loaded version
+ * if present.
+ *
+ * :param pkgconf_client_t* client: The client object to access.
+ * :param char* id: The package atom to look up in the client object's cache.
+ * :return: A package object if present, else ``NULL``.
+ * :rtype: pkgconf_pkg_t *
+ */
+pkgconf_pkg_t *
+pkgconf_cache_lookup(const pkgconf_client_t *client, const char *id)
+{
+ pkgconf_node_t *node;
+
+ PKGCONF_FOREACH_LIST_ENTRY(client->pkg_cache.head, node)
+ {
+ pkgconf_pkg_t *pkg = node->data;
+
+ if (!strcmp(pkg->id, id))
+ {
+ PKGCONF_TRACE(client, "found: %s @%p", id, pkg);
+ return pkgconf_pkg_ref(client, pkg);
+ }
+ }
+
+ PKGCONF_TRACE(client, "miss: %s", id);
+ return NULL;
+}
+
+/*
+ * !doc
+ *
+ * .. c:function:: void pkgconf_cache_add(pkgconf_client_t *client, pkgconf_pkg_t *pkg)
+ *
+ * Adds an entry for the package to the package cache.
+ * The cache entry must be removed if the package is freed.
+ *
+ * :param pkgconf_client_t* client: The client object to modify.
+ * :param pkgconf_pkg_t* pkg: The package object to add to the client object's cache.
+ * :return: nothing
+ */
+void
+pkgconf_cache_add(pkgconf_client_t *client, pkgconf_pkg_t *pkg)
+{
+ if (pkg == NULL)
+ return;
+
+ pkgconf_pkg_ref(client, pkg);
+ pkgconf_node_insert(&pkg->cache_iter, pkg, &client->pkg_cache);
+
+ PKGCONF_TRACE(client, "added @%p to cache", pkg);
+}
+
+/*
+ * !doc
+ *
+ * .. c:function:: void pkgconf_cache_remove(pkgconf_client_t *client, pkgconf_pkg_t *pkg)
+ *
+ * Deletes a package from the client object's package cache.
+ *
+ * :param pkgconf_client_t* client: The client object to modify.
+ * :param pkgconf_pkg_t* pkg: The package object to remove from the client object's cache.
+ * :return: nothing
+ */
+void
+pkgconf_cache_remove(pkgconf_client_t *client, pkgconf_pkg_t *pkg)
+{
+ if (pkg == NULL)
+ return;
+
+ PKGCONF_TRACE(client, "removed @%p from cache", pkg);
+
+ pkgconf_node_delete(&pkg->cache_iter, &client->pkg_cache);
+}
+
+/*
+ * !doc
+ *
+ * .. c:function:: void pkgconf_cache_free(pkgconf_client_t *client)
+ *
+ * Releases all resources related to a client object's package cache.
+ * This function should only be called to clear a client object's package cache,
+ * as it may release any package in the cache.
+ *
+ * :param pkgconf_client_t* client: The client object to modify.
+ */
+void
+pkgconf_cache_free(pkgconf_client_t *client)
+{
+ pkgconf_node_t *iter, *iter2;
+
+ PKGCONF_FOREACH_LIST_ENTRY_SAFE(client->pkg_cache.head, iter2, iter)
+ {
+ pkgconf_pkg_t *pkg = iter->data;
+ pkgconf_pkg_free(client, pkg);
+ }
+
+ memset(&client->pkg_cache, 0, sizeof client->pkg_cache);
+
+ PKGCONF_TRACE(client, "cleared package cache");
+}