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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
|
// Copyright (c) Copyright (c) Hercules Dev Team, licensed under GNU GPL.
// Copyright (c) 2018 Evol developers
#include "common/hercules.h"
#include <Judy.h>
#include <string.h>
#include "common/db.h"
#include "common/memmgr.h"
#include "emap/judyarray.h"
struct judy_interface judy_s;
struct judy_interface *judy;
int64 judy_new_array(void)
{
int64 id = judy->last_id++;
void **PJSLArray;
JLI(PJSLArray, judy->arrays, id);
*PJSLArray = (void *)NULL;
return id;
}
bool judy_destroy_array(int64 id)
{
int ret = 0;
judy->clear_array(id);
JLD(ret, judy->arrays, id);
return true;
}
bool judy_array_exists(int64 id)
{
void **PJSLArray;
JLG(PJSLArray, judy->arrays, id);
return PJSLArray != NULL;
}
int64 judy_array_size(int64 id)
{
void **PJSLArray;
JLG(PJSLArray, judy->arrays, id);
if (!PJSLArray)
return 0;
unsigned long sz = 0;
JLC(sz, *PJSLArray, 0, -1);
return sz;
}
bool judy_clear_array(int64 id)
{
void **PJSLArray;
JLG(PJSLArray, judy->arrays, id);
if (PJSLArray)
{
uint8_t key[1];
void **PValue;
key[0] = '\0';
JSLF(PValue, *PJSLArray, key);
while (PValue && *PValue)
{
const struct DBData *result = (struct DBData *)(*PValue);
if (result->type == DB_DATA_PTR)
aFree(result->u.ptr);
aFree(*PValue);
int ret = 0;
JSLD(ret, *PJSLArray, key);
JSLF(PValue, *PJSLArray, key);
}
return true;
}
return false;
}
const struct DBData* judy_getvalue(int64 id, const char *key, const struct DBData *defval)
{
void **PJSLArray;
void **PValue;
JLG(PJSLArray, judy->arrays, id);
if (!PJSLArray)
return defval; // array not found
JSLG(PValue, *PJSLArray, (unsigned char *)key);
if (PValue && *PValue)
return (struct DBData *)(*PValue);
return defval;
}
bool judy_setvalue(int64 id, const char *key, struct DBData *value)
{
void **PJSLArray;
JLG(PJSLArray, judy->arrays, id);
if (!PJSLArray)
{
if (value->type == DB_DATA_PTR)
aFree(value->u.ptr);
aFree(value);
return false; // array not found
}
bool keep = true;
switch(value->type)
{
case DB_DATA_INT:
case DB_DATA_UINT:
keep = value->u.i;
break;
case DB_DATA_PTR:
keep = value->u.ptr && *(char*)value->u.ptr;
break;
}
if (keep)
{
void **PValue;
JSLI(PValue, *PJSLArray, (unsigned char *)key);
if (PValue && *PValue)
{
const struct DBData *prev = (struct DBData *)(*PValue);
if (prev->type == DB_DATA_PTR)
aFree(prev->u.ptr);
aFree(*PValue); // free any previously-set struct
}
*PValue = value;
return true;
}
else
{
// check if it previously existed, and free it
{
void **PValue;
JSLG(PValue, *PJSLArray, (unsigned char *)key);
if (PValue && *PValue)
{
const struct DBData *prev = (struct DBData *)(*PValue);
if (prev->type == DB_DATA_PTR)
aFree(prev->u.ptr);
aFree(*PValue);
}
}
int ret = 0;
JSLD(ret, *PJSLArray, (unsigned char *)key);
}
if (value->type == DB_DATA_PTR)
aFree(value->u.ptr);
aFree(value);
return true;
}
/**
* Initializer.
*/
void judy_init(void)
{
judy->arrays = (void *)NULL; // this is a judyL array of judySL arrays
}
/**
* Finalizer.
*/
void judy_final(void)
{
for (int64 id = 1; id <= judy->last_id; id++)
judy->destroy_array(id);
unsigned long sz = 0;
JLFA(sz, judy->arrays);
judy->arrays = NULL;
}
/**
* Interface defaults initializer.
*/
void judy_defaults(void)
{
judy = &judy_s;
judy->last_id = 1;
judy->arrays = NULL;
judy->new_array = judy_new_array;
judy->clear_array = judy_clear_array;
judy->destroy_array = judy_destroy_array;
judy->array_exists = judy_array_exists;
judy->array_size = judy_array_size;
judy->getvalue = judy_getvalue;
judy->setvalue = judy_setvalue;
}
|