Refactor and add support for the ASCII protocol by wrapping the binary protocol
[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 return true;
20 }
21
22 void shutdown_storage(void) {
23 /* Do nothing */
24 }
25
26 void put_item(struct item* item) {
27 struct list_entry* entry= (void*)item;
28 update_cas(item);
29
30 if (root == NULL)
31 {
32 entry->next= entry->prev= entry;
33 }
34 else
35 {
36 entry->prev= root->prev;
37 entry->next= root;
38 entry->prev->next= entry;
39 entry->next->prev= entry;
40 }
41
42 root= entry;
43 }
44
45 struct item* get_item(const void* key, size_t nkey) {
46 struct list_entry *walker= root;
47 if (root == NULL)
48 {
49 return NULL;
50 }
51
52 do
53 {
54 if (((struct item*)walker)->nkey == nkey &&
55 memcmp(((struct item*)walker)->key, key, nkey) == 0)
56 {
57 return (struct item*)walker;
58 }
59 walker= walker->next;
60 } while (walker != root);
61
62 return NULL;
63 }
64
65 struct item* create_item(const void* key, size_t nkey, const void* data,
66 size_t size, uint32_t flags, time_t exp)
67 {
68 struct item* ret= calloc(1, sizeof(struct list_entry));
69 if (ret != NULL)
70 {
71 ret->key= malloc(nkey);
72 if (size > 0)
73 {
74 ret->data= malloc(size);
75 }
76
77 if (ret->key == NULL || (size > 0 && ret->data == NULL))
78 {
79 free(ret->key);
80 free(ret->data);
81 free(ret);
82 return NULL;
83 }
84
85 memcpy(ret->key, key, nkey);
86 if (data != NULL)
87 {
88 memcpy(ret->data, data, size);
89 }
90
91 ret->nkey= nkey;
92 ret->size= size;
93 ret->flags= flags;
94 ret->exp= exp;
95 }
96
97 return ret;
98 }
99
100 bool delete_item(const void* key, size_t nkey) {
101 struct item* item= get_item(key, nkey);
102 bool ret= false;
103
104 if (item)
105 {
106 /* remove from linked list */
107 struct list_entry *entry= (void*)item;
108
109 if (entry->next == entry)
110 {
111 /* Only one object in the list */
112 root= NULL;
113 }
114 else
115 {
116 /* ensure that we don't loose track of the root, and this will
117 * change the start position for the next search ;-) */
118 root= entry->next;
119 entry->prev->next= entry->next;
120 entry->next->prev= entry->prev;
121 }
122
123 free(item->key);
124 free(item->data);
125 free(item);
126 ret= true;
127 }
128
129 return ret;
130 }
131
132 void flush(uint32_t when) {
133 /* FIXME */
134 (void)when;
135 /* remove the complete linked list */
136 if (root == NULL)
137 {
138 return;
139 }
140
141 root->prev->next= NULL;
142 while (root != NULL)
143 {
144 struct item* tmp= (void*)root;
145 root= root->next;
146
147 free(tmp->key);
148 free(tmp->data);
149 free(tmp);
150 }
151 }
152
153 void update_cas(struct item* item) {
154 item->cas= ++cas;
155 }
156
157 void release_item(struct item* item __attribute__((unused))) {
158 /* EMPTY */
159 }