-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathminibloom.c
172 lines (150 loc) · 3.91 KB
/
minibloom.c
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
#include <lua.h>
#include "lauxlib.h"
#include "lualib.h"
#include <string.h>
#include <errno.h>
#include <limits.h>
#include "minibloom.h"
#include "minibloomfile.h"
/* Lua exception */
static int lua_oops(lua_State *L, const char *s)
{
char buffer[1024];
if(!s) return 0;
snprintf(buffer, sizeof(buffer), "%s: error: %s", s, strerror(errno));
buffer[sizeof(buffer)-1] = '\0';
lua_pushstring(L, buffer);
return lua_error(L);
}
static int lua_oops_str(lua_State *L, const char *s, char* ss)
{
char buffer[1024];
if(!s) return 0;
snprintf(buffer, sizeof(buffer), "%s: '%s': error: %s", s, ss, strerror(errno));
buffer[sizeof(buffer)-1] = '\0';
lua_pushstring(L, buffer);
return lua_error(L);
}
static int luabind_minimake(lua_State *L)
{
minibloomfile_t* mib;
int err;
const char* filename;
unsigned int capacity;
double error_rate;
// Args:
filename = lua_tolstring(L, -3, NULL);
if (!filename) {
return lua_oops(L, "minibloom_create_filter: missing filename");
}
if (!lua_isnumber(L, -2)) {
return lua_oops(L, "minibloom_create_filter: bad capacity");
}
capacity = lua_tointeger(L, -2);
if (!lua_isnumber(L, -1)) {
return lua_oops(L, "minibloom_create_filter: bad error rate");
}
error_rate = lua_tonumber(L, -1);
// Create the new bloom filter:
mib = (minibloomfile_t*) lua_newuserdata (L, sizeof(minibloomfile_t));
err = minimake(mib, filename, capacity, error_rate);
if (err) {
lua_pop(L,1);
return lua_oops(L, "minimake: error making bloom filter");
}
return 1;
}
static int luabind_miniload(lua_State *L)
{
minibloomfile_t*mib;
int append;
const char * filename;
// Arguments:
filename = lua_tolstring(L, -1, NULL);
if (!filename) {
return lua_oops(L, "minibloom_open: missing filename");
}
append = lua_tointeger(L, -2); // If missing this should be 0 which is fine. 0 == readonly
mib = (minibloomfile_t*) lua_newuserdata (L, sizeof(minibloomfile_t));
if (miniload(mib, filename, append)) {
lua_pop(L,1);
return lua_oops_str(L, "minibloom_open: error opening mib filter", filename);
}
return 1;
}
static int luabind_miniclose(lua_State *L)
{
minibloomfile_t* mib;
if (!lua_isuserdata(L, -1)) {
return lua_oops(L, "minibloom_close: not a minibloom filter");
}
mib = (minibloomfile_t*) lua_touserdata(L, -1);
if (minicheckfilehandle(mib)) {
return lua_oops(L, "minibloom_close: not a minibloom filter");
}
miniclose(mib);
return 0;
}
static int luabind_minigetbloom(lua_State *L)
{
minibloomfile_t* mib;
if (!lua_isuserdata(L,-1)){
return lua_oops(L, "minibloom_getbloom: not a minibloom filter: wrong type");
}
mib = lua_touserdata(L, -1);
if (minicheckfilehandle(mib)) {
return lua_oops(L, "minibloom_getbloom: not a minibloom filter: bad content");
}
lua_pushlightuserdata(L, mib->bloom);
return 1;
}
static int luabind_miniget(lua_State *L)
{
minibloom_t* mib;
const char *key;
size_t keylen;
if (!lua_isuserdata(L, -2)) {
return lua_oops(L, "minibloom_get: not minibloom filter");
}
mib = lua_touserdata(L, -2);
key = lua_tolstring(L, -1, &keylen);
if (!key) {
return lua_oops(L, "minibloom_get: missing key");
}
int v = miniget(mib, key, keylen);
lua_pushinteger(L, v);
return 1;
}
static int luabind_miniset(lua_State *L)
{
minibloom_t* mib;
const char *key;
size_t keylen;
if (!lua_islightuserdata(L, -2)) {
return lua_oops(L, "minibloom_set: not a minibloom filter");
}
mib = lua_touserdata(L, -2);
key = lua_tolstring(L, -1, &keylen);
if (!key) {
return lua_oops(L, "minibloom_set: missing key");
}
miniset(mib, key, keylen);
return 0;
}
static const luaL_Reg api[] = {
{"make" , luabind_minimake},
{"open" , luabind_miniload},
{"close", luabind_miniclose},
{"bloom", luabind_minigetbloom},
{"get" , luabind_miniget},
{"set" , luabind_miniset},
{NULL, NULL}
};
int luaopen_minibloom (lua_State *L) {
#if LUA_VERSION_NUM <= 501
luaL_register(L, "minibloom", api); /* 5.1 */
#else
luaL_newlib(L, api); /* 5.2 */
#endif
return 1;
}