summaryrefslogtreecommitdiffstats
path: root/usr.sbin/nscd/cachelib.h
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/nscd/cachelib.h')
-rw-r--r--usr.sbin/nscd/cachelib.h281
1 files changed, 281 insertions, 0 deletions
diff --git a/usr.sbin/nscd/cachelib.h b/usr.sbin/nscd/cachelib.h
new file mode 100644
index 0000000..d67e830
--- /dev/null
+++ b/usr.sbin/nscd/cachelib.h
@@ -0,0 +1,281 @@
+/*-
+ * Copyright (c) 2005 Michael Bushkov <bushman@rsu.ru>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __CACHED_CACHELIB_H__
+#define __CACHED_CACHELIB_H__
+
+#include <sys/queue.h>
+#include <sys/time.h>
+#include <stdlib.h>
+#include "hashtable.h"
+#include "cacheplcs.h"
+
+enum cache_entry_t {
+ CET_COMMON = 0, /* cache item is atomic */
+ CET_MULTIPART /* cache item is formed part by part */
+};
+
+enum cache_transformation_t {
+ CTT_FLUSH = 0, /* flush the cache - delete all obsolete items */
+ CTT_CLEAR = 1 /* delete all items in the cache */
+};
+
+/* cache deletion policy type enum */
+enum cache_policy_t {
+ CPT_FIFO = 0, /* first-in first-out */
+ CPT_LRU = 1, /* least recently used */
+ CPT_LFU = 2 /* least frequently used */
+};
+
+/* multipart sessions can be used for reading and writing */
+enum cache_mp_session_t {
+ CMPT_READ_SESSION,
+ CMPT_WRITE_SESSION
+};
+
+/*
+ * When doing partial transformations of entries (which are applied for
+ * elements with keys, that contain specified buffer in its left or
+ * right part), this enum will show the needed position of the key part.
+ */
+enum part_position_t {
+ KPPT_LEFT,
+ KPPT_RIGHT
+};
+
+/* num_levels attribute is obsolete, i think - user can always emulate it
+ * by using one entry.
+ * get_time_func is needed to have the clocks-independent counter
+ */
+struct cache_params
+{
+ void (*get_time_func)(struct timeval *);
+};
+
+/*
+ * base structure - normal_cache_entry_params and multipart_cache_entry_params
+ * are "inherited" from it
+ */
+struct cache_entry_params
+{
+ enum cache_entry_t entry_type;
+ char *entry_name;
+};
+
+/* params, used for most entries */
+struct common_cache_entry_params
+{
+ /* inherited fields */
+ enum cache_entry_t entry_type;
+
+ /* unique fields */
+ char *entry_name;
+ size_t cache_entries_size;
+
+ size_t max_elemsize; /* if 0 then no check is made */
+ size_t satisf_elemsize; /* if entry size is exceeded,
+ * this number of elements will be left,
+ * others will be deleted */
+ struct timeval max_lifetime; /* if 0 then no check is made */
+ enum cache_policy_t policy; /* policy used for transformations */
+};
+
+/* params, used for multipart entries */
+struct mp_cache_entry_params
+{
+ /* inherited fields */
+ enum cache_entry_t entry_type;
+ char *entry_name;
+
+ /* unique fields */
+ size_t max_elemsize; /* if 0 then no check is made */
+ size_t max_sessions; /* maximum number of active sessions */
+
+ struct timeval max_lifetime; /* maximum elements lifetime */
+};
+
+struct cache_ht_item_data_
+{
+ /* key is the bytes sequence only - not the null-terminated string */
+ char *key;
+ size_t key_size;
+
+ char *value;
+ size_t value_size;
+
+ struct cache_policy_item_ *fifo_policy_item;
+};
+
+struct cache_ht_item_
+{
+ HASHTABLE_ENTRY_HEAD(ht_item_, struct cache_ht_item_data_) data;
+};
+
+struct cache_entry_
+{
+ char *name;
+ struct cache_entry_params *params;
+};
+
+struct cache_common_entry_
+{
+ char *name;
+ struct cache_entry_params *params;
+
+ struct common_cache_entry_params common_params;
+
+ HASHTABLE_HEAD(cache_ht_, cache_ht_item_) items;
+ size_t items_size;
+
+ /*
+ * Entry always has the FIFO policy, that is used to eliminate old
+ * elements (the ones, with lifetime more than max_lifetime). Besides,
+ * user can specify another policy to be applied, when there are too
+ * many elements in the entry. So policies_size can be 1 or 2.
+ */
+ struct cache_policy_ **policies;
+ size_t policies_size;
+
+ void (*get_time_func)(struct timeval *);
+};
+
+struct cache_mp_data_item_ {
+ char *value;
+ size_t value_size;
+
+ TAILQ_ENTRY(cache_mp_data_item_) entries;
+};
+
+struct cache_mp_write_session_
+{
+ struct cache_mp_entry_ *parent_entry;
+
+ /*
+ * All items are accumulated in this queue. When the session is
+ * committed, they all will be copied to the multipart entry.
+ */
+ TAILQ_HEAD(cache_mp_data_item_head, cache_mp_data_item_) items;
+ size_t items_size;
+
+ TAILQ_ENTRY(cache_mp_write_session_) entries;
+};
+
+struct cache_mp_read_session_
+{
+ struct cache_mp_entry_ *parent_entry;
+ struct cache_mp_data_item_ *current_item;
+
+ TAILQ_ENTRY(cache_mp_read_session_) entries;
+};
+
+struct cache_mp_entry_
+{
+ char *name;
+ struct cache_entry_params *params;
+
+ struct mp_cache_entry_params mp_params;
+
+ /* All opened write sessions */
+ TAILQ_HEAD(write_sessions_head, cache_mp_write_session_) ws_head;
+ size_t ws_size;
+
+ /* All opened read sessions */
+ TAILQ_HEAD(read_sessions_head, cache_mp_read_session_) rs_head;
+ size_t rs_size;
+
+ /*
+ * completed_write_session is the committed write sessions. All read
+ * sessions use data from it. If the completed_write_session is out of
+ * date, but still in use by some of the read sessions, the newly
+ * committed write session is stored in the pending_write_session.
+ * In such a case, completed_write_session will be substituted with
+ * pending_write_session as soon as it won't be used by any of
+ * the read sessions.
+ */
+ struct cache_mp_write_session_ *completed_write_session;
+ struct cache_mp_write_session_ *pending_write_session;
+ struct timeval creation_time;
+ struct timeval last_request_time;
+
+ void (*get_time_func)(struct timeval *);
+};
+
+struct cache_
+{
+ struct cache_params params;
+
+ struct cache_entry_ **entries;
+ size_t entries_capacity;
+ size_t entries_size;
+};
+
+/* simple abstractions - for not to write "struct" every time */
+typedef struct cache_ *cache;
+typedef struct cache_entry_ *cache_entry;
+typedef struct cache_mp_write_session_ *cache_mp_write_session;
+typedef struct cache_mp_read_session_ *cache_mp_read_session;
+
+#define INVALID_CACHE (NULL)
+#define INVALID_CACHE_ENTRY (NULL)
+#define INVALID_CACHE_MP_WRITE_SESSION (NULL)
+#define INVALID_CACHE_MP_READ_SESSION (NULL)
+
+/*
+ * NOTE: all cache operations are thread-unsafe. You must ensure thread-safety
+ * externally, by yourself.
+ */
+
+/* cache initialization/destruction routines */
+extern cache init_cache(struct cache_params const *);
+extern void destroy_cache(cache);
+
+/* cache entries manipulation routines */
+extern int register_cache_entry(cache, struct cache_entry_params const *);
+extern int unregister_cache_entry(cache, const char *);
+extern cache_entry find_cache_entry(cache, const char *);
+
+/* read/write operations used on common entries */
+extern int cache_read(cache_entry, const char *, size_t, char *, size_t *);
+extern int cache_write(cache_entry, const char *, size_t, char const *, size_t);
+
+/* read/write operations used on multipart entries */
+extern cache_mp_write_session open_cache_mp_write_session(cache_entry);
+extern int cache_mp_write(cache_mp_write_session, char *, size_t);
+extern void abandon_cache_mp_write_session(cache_mp_write_session);
+extern void close_cache_mp_write_session(cache_mp_write_session);
+
+extern cache_mp_read_session open_cache_mp_read_session(cache_entry);
+extern int cache_mp_read(cache_mp_read_session, char *, size_t *);
+extern void close_cache_mp_read_session(cache_mp_read_session);
+
+/* transformation routines */
+extern int transform_cache_entry(cache_entry, enum cache_transformation_t);
+extern int transform_cache_entry_part(cache_entry, enum cache_transformation_t,
+ const char *, size_t, enum part_position_t);
+
+#endif
OpenPOWER on IntegriCloud