aboutsummaryrefslogtreecommitdiff
path: root/tests/lru_cache/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/lru_cache/main.c')
-rw-r--r--tests/lru_cache/main.c191
1 files changed, 191 insertions, 0 deletions
diff --git a/tests/lru_cache/main.c b/tests/lru_cache/main.c
new file mode 100644
index 000000000..7f0eae2f2
--- /dev/null
+++ b/tests/lru_cache/main.c
@@ -0,0 +1,191 @@
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "cache.h"
+
+#define MAX_RANDOM_ENTRIES 32
+
+struct key_record {
+ char *key;
+ char *value;
+};
+
+int generate_random_entry(struct key_record **entry);
+int generate_random_string(char **dst, const size_t len);
+void free_random_entry(void *entry);
+
+void *producer(void *arg)
+{
+ struct foo_cache *cache = arg;
+ int i;
+
+ for (i = 0; i < MAX_RANDOM_ENTRIES; i++) {
+ struct key_record *entry = NULL;
+ if (generate_random_entry(&entry)) {
+ fprintf(stderr, "generate_random_entry() failed\n");
+ continue;
+ }
+#if defined(DEBUG)
+ printf("Random Entry:\n");
+ printf(" key: %s\n", entry->key);
+ printf(" Key: %s\n", entry->value);
+#else
+ printf("inserted %s (%d)\n", entry->key,
+ (int)strlen(entry->key));
+#endif
+ if (foo_cache_insert(cache, entry->key, entry)) {
+ fprintf(stderr, "foo_cache_insert() failed\n");
+ continue;
+ }
+ }
+
+ pthread_exit(NULL);
+}
+
+void *consumer(void *arg)
+{
+ struct foo_cache *cache = arg;
+ struct key_record *result = NULL;
+ char *buffer = malloc(64);
+ char key[33];
+ int stop = 0;
+
+ if (!buffer)
+ goto out;
+
+ /* give producer time to populate the cache */
+ sleep(2);
+ printf("\n\n");
+
+ do {
+ memset(key, 0, 64);
+ result = NULL;
+
+ printf("Enter key for lookup: ");
+ fgets(buffer, sizeof(key), stdin);
+ sscanf(buffer, "%s\n", key);
+ /* read '\n' from stdin */
+ getchar();
+
+ if (strncmp(key, "exit", 4) == 0) {
+ stop = 1;
+ continue;
+ }
+
+ printf("Got key %s (%d)\n", key, (int)strlen(key));
+
+ if (foo_cache_lookup(cache, key, &result)) {
+ fprintf(stderr, "Could not retrieve key %s\n", key);
+ continue;
+ }
+
+ if (!result) {
+ printf("MISS\n");
+ continue;
+ }
+
+ printf("HIT\n");
+ printf("key: %s\n", result->key);
+ printf("key : %s\n", result->value);
+ } while (!stop);
+
+out:
+ if (buffer)
+ free(buffer);
+ pthread_exit(NULL);
+}
+
+int main()
+{
+ int rv;
+ struct foo_cache *cache = NULL;
+ pthread_t workers[2];
+
+ rv = foo_cache_create(&cache, MAX_RANDOM_ENTRIES / 2,
+ free_random_entry);
+ if (rv) {
+ fprintf(stderr, "Could not create cache\n");
+ exit(1);
+ }
+
+ (void)pthread_create(&workers[0], NULL, producer, (void *)cache);
+ (void)pthread_create(&workers[1], NULL, consumer, (void *)cache);
+
+ pthread_join(workers[0], NULL);
+ pthread_join(workers[1], NULL);
+
+ (void)foo_cache_delete(cache, 0);
+ return 0;
+}
+
+int generate_random_entry(struct key_record **entry)
+{
+ struct key_record *new = NULL;
+ char *key = NULL;
+ char *value = NULL;
+ int rv;
+
+ if (!entry)
+ return EINVAL;
+
+ rv = generate_random_string(&key, 33);
+ if (rv)
+ return rv;
+
+ rv = generate_random_string(&value, 129);
+ if (rv)
+ return rv;
+
+ if ((new = malloc(sizeof(*new))) == NULL) {
+ free(key);
+ free(value);
+ return ENOMEM;
+ }
+
+ new->key = key;
+ new->value = value;
+
+ *entry = new;
+ return 0;
+}
+
+int generate_random_string(char **dst, const size_t len)
+{
+ static const char alphanum[] =
+ "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+ size_t i;
+ char *s;
+
+ if (!dst || len == 0)
+ return EINVAL;
+
+ if ((s = malloc(len)) == NULL)
+ return ENOMEM;
+
+ for (i = 0; i < len - 1; i++) {
+ s[i] = alphanum[rand() % (sizeof(alphanum) - 1)];
+ }
+
+ s[len - 1] = '\0';
+ *dst = s;
+ return 0;
+}
+
+void free_random_entry(void *entry)
+{
+#if defined(DEBUG)
+ fprintf(stderr, "In %s: entry @ %p\n", __func__, entry);
+#endif
+ struct key_record *record = entry;
+ if (!record)
+ return;
+ if (record->key)
+ free(record->key);
+ if (record->value)
+ free(record->value);
+ free(record);
+ record = NULL;
+}