static int bloom_filter_query(lua_State* lua) { bloom_filter* bf = check_bloom_filter(lua, 2); size_t len = 0; double val = 0; void* key = NULL; switch (lua_type(lua, 2)) { case LUA_TSTRING: key = (void*)lua_tolstring(lua, 2, &len); break; case LUA_TNUMBER: val = lua_tonumber(lua, 2); len = sizeof(double); key = &val; break; default: luaL_argerror(lua, 2, "must be a string or number"); break; } unsigned int bit = 0; int found = 1; for (unsigned int i = 0; i < bf->hashes && found; ++i) { bit = XXH32(key, (int)len, i) % bf->bits; found = bf->data[bit / CHAR_BIT] & 1 << (bit % CHAR_BIT); } lua_pushboolean(lua, found); return 1; }
static int bloom_filter_clear(lua_State* lua) { bloom_filter* bf = check_bloom_filter(lua, 1); memset(bf->data, 0, bf->bytes); bf->cnt = 0; return 0; }
static int bloom_filter_fromstring(lua_State* lua) { size_t len = 0; const char* values = NULL; bloom_filter* bf = NULL; if (lua_gettop(lua) == 2) { // todo remove conditional check after migration bf = check_bloom_filter(lua, 2); values = luaL_checklstring(lua, 2, &len); } else { bf = check_bloom_filter(lua, 3); bf->cnt = (size_t)luaL_checknumber(lua, 2); values = luaL_checklstring(lua, 3, &len); } if (len != bf->bytes) { luaL_error(lua, "fromstring() bytes found: %d, expected %d", len, bf->bytes); } memcpy(bf->data, values, len); return 0; }
static int bloom_filter_fromstring(lua_State* lua) { bloom_filter* bf = check_bloom_filter(lua, 2); size_t len = 0; const char* values = luaL_checklstring(lua, 2, &len); if (len != bf->bytes) { luaL_error(lua, "fromstring() bytes found: %d, expected %d", len, bf->bytes); } memcpy(bf->data, values, len); return 0; }
static int bloom_filter_tostring(lua_State* lua) { bloom_filter* bf = check_bloom_filter(lua, 1); lua_pushlstring(lua, (const char*)bf->data, bf->bytes); return 1; }
static int bloom_filter_bytes(lua_State* lua) { bloom_filter* bf = check_bloom_filter(lua, 1); lua_pushnumber(lua, (lua_Number)bf->bytes); return 1; }
static int bloom_filter_probability(lua_State* lua) { bloom_filter* bf = check_bloom_filter(lua, 1); lua_pushnumber(lua, (lua_Number)bf->probability); return 1; }
static int bloom_filter_count(lua_State* lua) { bloom_filter* bf = check_bloom_filter(lua, 1); lua_pushnumber(lua, (lua_Number)bf->cnt); return 1; }