def _get_hashes(key, filters_params): params_true, params_false = filters_params index_size_true, number_of_hashes_true = params_true index_size_false, number_of_hashes_false = params_false hashes_true = get_hashes(key + "true", number_of_hashes_true, index_size_true) hashes_false = get_hashes(key + "false", number_of_hashes_false, index_size_false) return hashes_true, hashes_false
async def __set(*args: Any, **kwargs: Any): if _set is None: result = await func(*args, **kwargs) else: result = await _set(*args, **kwargs) if not result: return result _bloom_key = get_cache_key(func, _name, args, kwargs) hashes = get_hashes(_bloom_key, number_of_hashes, index_size) await backend.incr_bits(_cache_key, *hashes) return result
async def _wrap(*args, **kwargs): _bloom_key = get_cache_key(func, _name, args, kwargs) hashes = get_hashes(_bloom_key, number_of_hashes, index_size) values = await backend.get_bits(_cache_key, *hashes) if values is None: return await func(*args, **kwargs) if all_not_zeros(values): # if all bits is set # false positive if check_false_positive: return await func(*args, **kwargs) return True else: return False
async def _wrap(*args, **kwargs): _bloom_key = get_cache_key(func, _name, args, kwargs) hashes = get_hashes(_bloom_key, number_of_hashes, index_size) values = await backend.get_bits(_cache_key, *hashes, size=2) if at_least_one_zero(values): return False if all(values): if not check_false_positive: return True result = await func(*args, **kwargs) assert isinstance(result, bool) if result: await backend.incr_bits(_cache_key, *hashes, size=2, by=3) else: await backend.incr_bits(_cache_key, *hashes, size=2, by=1) return result
def test_get_hashes(): assert get_hashes("test", 10, 1000) == get_hashes("test", 10, 1000) assert get_hashes("test", 2, 2) == get_hashes("test", 2, 2) assert get_hashes("test", 2, 5) != get_hashes("test", 2, 2) assert get_hashes("test", 3, 100) != get_hashes("tset", 3, 100) assert get_hashes("test", 3, 100) != get_hashes("t", 3, 100) assert get_hashes("test", 3, 100) != get_hashes("tes", 3, 100) assert get_hashes("test", 3, 100) != get_hashes("test2", 3, 100) assert not get_hashes("test", 5, 100).intersection(get_hashes("a", 5, 100)) assert not get_hashes("test", 5, 100).intersection(get_hashes("test2", 5, 100)) assert get_hashes("test", 3, 3) == get_hashes("a", 3, 3) # it is ok to have collisions in this case assert len(get_hashes("test", 20, 100)) == len(set(get_hashes("test", 20, 100)))
def test_get_hashes_params(): assert len(get_hashes("test", 3, 3)) == 3 assert len(get_hashes("test", 1, 100)) == 1 assert len(get_hashes("test", 77, 100)) == 77 assert len(get_hashes("long string hash", 77, 100)) == 77 assert get_hashes("test", 1, 100).pop() < 100
async def _set(*args: Any, **kwargs: Any) -> None: _bloom_key = get_cache_key(func, _name, args, kwargs) hashes = get_hashes(_bloom_key, number_of_hashes, index_size) await backend.incr_bits(_cache_key, *hashes, size=2, by=1)