]> mj.ucw.cz Git - libucw.git/commitdiff
First steps towards a universal shared memory cache, which will be used
authorMartin Mares <mj@ucw.cz>
Sun, 6 Mar 2005 12:26:13 +0000 (12:26 +0000)
committerMartin Mares <mj@ucw.cz>
Sun, 6 Mar 2005 12:26:13 +0000 (12:26 +0000)
in the multiplexer and later probably also in the search server.

lib/qache.c [new file with mode: 0644]
lib/qache.h [new file with mode: 0644]

diff --git a/lib/qache.c b/lib/qache.c
new file mode 100644 (file)
index 0000000..9f50b3c
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ *      Simple and Quick Shared Memory Cache
+ *
+ *     (c) 2005 Martin Mares <mj@ucw.cz>
+ */
+
+#include "sherlock/sherlock.h"
+
+#include <sys/mman.h>
+
+/* FIXME: do we really need to msync() the regions on Linux? */
+
+/*
+ *  On-disk format:
+ *     qache_header
+ *     qache_entry[max_entries]        table of entries and their keys
+ *     u32 qache_hash[hash_size]       hash table pointing to keys
+ *     padding                         to a multiple of block size
+ *     blocks[]                        data blocks, each block starts with u32 next_ptr
+ */
+
+struct qache_header {
+  u32 magic;                           /* QCACHE_MAGIC */
+  u32 block_size;                      /* Parameters as in qache_params */
+  u32 num_blocks;
+  u32 format_id;
+  u32 entry_table_start;               /* Array of qache_entry's */
+  u32 max_entries;
+  u32 hash_table_start;                        /* Hash table containing all keys */
+  u32 hash_size;
+  u32 lru_first;                       /* First entry in the LRU */
+  u32 first_free_entry;                        /* Head of the list of free entries */
+  u32 first_free_block;                        /* Head of the list of free blocks */
+};
+
+#define QACHE_MAGIC 0xb79f6d12
+
+struct qache_entry {
+  u32 lru_prev, lru_next;
+  u32 data_len;                                /* ~0 if a free entry */
+  u32 first_data_block;                        /* next free if a free entry */
+  qache_key_t key;
+  u32 hash_next;
+};
+
+struct qache {
+  struct qache_header *hdr;
+  int fd;
+  byte *mmap_data;
+  uns file_size;
+};
diff --git a/lib/qache.h b/lib/qache.h
new file mode 100644 (file)
index 0000000..b5d65f1
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ *      Simple and Quick Shared Memory Cache
+ *
+ *     (c) 2005 Martin Mares <mj@ucw.cz>
+ */
+
+#ifndef _UCW_QACHE_H
+#define _UCW_QACHE_H
+
+struct qache_params {
+  byte *file_name;
+  uns block_size;                      /* Cache block size (a power of two) */
+  uns cache_size;                      /* Size of the whole cache */
+  int force_reset;                     /* Force creation of a new cache even if the old one seems usable, -1 if reset should never be done */
+  uns format_id;                       /* Data format ID (old cache not used if formats differ) */
+};
+
+typedef byte qache_key_t[16];
+
+/* Create and destroy a cache */
+struct qache *qache_init(struct qache_params *p);
+void qache_cleanup(struct qache *q, uns retain_data);
+
+/* Insert new item to the cache with a given key and data. If pos_hint is non-zero, it serves
+ * as a hint about the position of the entry (if it's known that an entry with the particular key
+ * was located there a moment ago. Returns position of the new entry.
+ */
+uns qache_insert(struct qache *q, qache_key_t *key, uns pos_hint, void *data, uns size);
+
+/* Look up data in the cache, given a key and a position hint (as above). If datap is non-NULL, data
+ * from the cache entry are copied either to *datap (if *datap is NULL, new memory is allocated by
+ * calling xmalloc and *datap is set to point to that memory). The *sizep contains the maximum number
+ * of bytes to be copied (~0U if unlimited) and it is replaced by the number of bytes available (so it
+ * can be greater than the original value requested). The start indicates starting offset inside the
+ * entry's data.
+ */
+uns qache_lookup(struct qache *q, qache_key_t *key, uns pos_hint, void **datap, uns **sizep, uns start);
+
+/* Delete data from the cache, given a key and a position hint. */
+uns qache_delete(struct qache *q, qache_key_t *key, uns pos_hint);
+
+#endif