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