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