Merge Monty.
[m6w6/libmemcached] / example / storage.c
1 /* -*- Mode: C; tab-width: 2; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2 #include <stdlib.h>
3 #include <inttypes.h>
4 #include <time.h>
5 #include <stdbool.h>
6 #include <string.h>
7 #include "storage.h"
8
9 struct list_entry {
10 struct item item;
11 struct list_entry *next;
12 struct list_entry *prev;
13 };
14
15 static struct list_entry *root;
16 static uint64_t cas;
17
18 bool initialize_storage(void)
19 {
20 return true;
21 }
22
23 void shutdown_storage(void)
24 {
25 /* Do nothing */
26 }
27
28 void put_item(struct item* item)
29 {
30 struct list_entry* entry= (void*)item;
31
32 update_cas(item);
33
34 if (root == NULL)
35 {
36 entry->next= entry->prev= entry;
37 }
38 else
39 {
40 entry->prev= root->prev;
41 entry->next= root;
42 entry->prev->next= entry;
43 entry->next->prev= entry;
44 }
45
46 root= entry;
47 }
48
49 struct item* get_item(const void* key, size_t nkey)
50 {
51 struct list_entry *walker= root;
52
53 if (root == NULL)
54 {
55 return NULL;
56 }
57
58 do
59 {
60 if (((struct item*)walker)->nkey == nkey &&
61 memcmp(((struct item*)walker)->key, key, nkey) == 0)
62 {
63 return (struct item*)walker;
64 }
65 walker= walker->next;
66 } while (walker != root);
67
68 return NULL;
69 }
70
71 struct item* create_item(const void* key, size_t nkey, const void* data,
72 size_t size, uint32_t flags, time_t exp)
73 {
74 struct item* ret= calloc(1, sizeof(struct list_entry));
75
76 if (ret != NULL)
77 {
78 ret->key= malloc(nkey);
79 if (size > 0)
80 {
81 ret->data= malloc(size);
82 }
83
84 if (ret->key == NULL || (size > 0 && ret->data == NULL))
85 {
86 free(ret->key);
87 free(ret->data);
88 free(ret);
89 return NULL;
90 }
91
92 memcpy(ret->key, key, nkey);
93 if (data != NULL)
94 {
95 memcpy(ret->data, data, size);
96 }
97
98 ret->nkey= nkey;
99 ret->size= size;
100 ret->flags= flags;
101 ret->exp= exp;
102 }
103
104 return ret;
105 }
106
107 bool delete_item(const void* key, size_t nkey)
108 {
109 struct item* item= get_item(key, nkey);
110 bool ret= false;
111
112 if (item)
113 {
114 /* remove from linked list */
115 struct list_entry *entry= (void*)item;
116
117 if (entry->next == entry)
118 {
119 /* Only one object in the list */
120 root= NULL;
121 }
122 else
123 {
124 /* ensure that we don't loose track of the root, and this will
125 * change the start position for the next search ;-) */
126 root= entry->next;
127 entry->prev->next= entry->next;
128 entry->next->prev= entry->prev;
129 }
130
131 free(item->key);
132 free(item->data);
133 free(item);
134 ret= true;
135 }
136
137 return ret;
138 }
139
140 void flush(uint32_t when)
141 {
142 /* FIXME */
143 (void)when;
144 /* remove the complete linked list */
145 if (root == NULL)
146 {
147 return;
148 }
149
150 root->prev->next= NULL;
151 while (root != NULL)
152 {
153 struct item* tmp= (void*)root;
154 root= root->next;
155
156 free(tmp->key);
157 free(tmp->data);
158 free(tmp);
159 }
160 }
161
162 void update_cas(struct item* item)
163 {
164 item->cas= ++cas;
165 }
166
167 void release_item(struct item* item __attribute__((unused)))
168 {
169 /* EMPTY */
170 }