diff options
| author | ruki <[email protected]> | 2022-05-21 18:54:53 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2022-05-21 18:54:53 +0800 |
| commit | d6450df88afc0fb971f4c23d6ff1e81673730cea (patch) | |
| tree | 0eb3989874cb916babfc764797a933c12f25a1a6 | |
| parent | 24100a60c3c3fd542079e71a65833dbf5816f25b (diff) | |
add bloom filter stub
| -rw-r--r-- | xmake/core/base/bloom_filter.lua | 198 | ||||
| -rw-r--r-- | xmake/core/compress/lz4.lua | 4 |
2 files changed, 200 insertions, 2 deletions
diff --git a/xmake/core/base/bloom_filter.lua b/xmake/core/base/bloom_filter.lua new file mode 100644 index 000000000..781cfb4da --- /dev/null +++ b/xmake/core/base/bloom_filter.lua @@ -0,0 +1,198 @@ +--!A cross-platform build utility based on Lua +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015-present, TBOOX Open Source Group. +-- +-- @author ruki +-- @file bloom_filter.lua +-- + +-- define module: bloom_filter +local bloom_filter = bloom_filter or {} +local _instance = _instance or {} + +-- load modules +local io = require("base/io") +local utils = require("base/utils") +local bytes = require("base/bytes") +local table = require("base/table") + +-- save metatable and builtin functions +bloom_filter._open = bloom_filter._open or bloom_filter.open +bloom_filter._close = bloom_filter._close or bloom_filter.close +bloom_filter._data = bloom_filter._data or bloom_filter.data +bloom_filter._size = bloom_filter._size or bloom_filter.size +bloom_filter._data_set = bloom_filter._data_set or bloom_filter.data_set +bloom_filter._clear = bloom_filter._clear or bloom_filter.clear +bloom_filter._set = bloom_filter._set or bloom_filter.set +bloom_filter._get = bloom_filter._get or bloom_filter.get + +-- the bloom filter probability +bloom_filter.PROBABILITY_0_1 = 3 -- 1 / 2^3 = 0.125 ~= 0.1 +bloom_filter.PROBABILITY_0_01 = 6 -- 1 / 2^6 = 0.015625 ~= 0.01 +bloom_filter.PROBABILITY_0_001 = 10 -- 1 / 2^10 = 0.0009765625 ~= 0.001 +bloom_filter.PROBABILITY_0_0001 = 13 -- 1 / 2^13 = 0.0001220703125 ~= 0.0001 +bloom_filter.PROBABILITY_0_00001 = 16 -- 1 / 2^16 = 0.0000152587890625 ~= 0.00001 +bloom_filter.PROBABILITY_0_000001 = 20 -- 1 / 2^20 = 0.00000095367431640625 ~= 0.000001 + +-- new a bloom filter +function _instance.new(handle) + local instance = table.inherit(_instance) + instance._HANDLE = handle + setmetatable(instance, _instance) + return instance +end + +-- get cdata of the bloom filter +function _instance:cdata() + return self._HANDLE +end + +-- get the bloom filter data +function _instance:data() + -- ensure opened + local ok, errors = self:_ensure_opened() + if not ok then + return nil, errors + end + + -- get the bloom filter data + local data = bloom_filter._data(self:cdata()) + local size = bloom_filter._size(self:cdata()) + if not data or size == 0 then + return nil, "no data!" + end + + -- mount this data + return bytes(size, data) +end + +-- set the bloom filter data +function _instance:data_set(data) + -- ensure opened + local ok, errors = self:_ensure_opened() + if not ok then + return false, errors + end + + -- set data + local datasize = data:size() + local dataaddr = data:caddr() + if not dataaddr or datasize == 0 then + return false, "empty data!" + end + return bloom_filter._data_set(self:cdata(), dataaddr, datasize) +end + +-- clear the bloom filter data +function _instance:clear() + -- ensure opened + local ok, errors = self:_ensure_opened() + if not ok then + return false, errors + end + + -- do clear + return bloom_filter._clear(self:cdata()) +end + +-- set the bloom filter data item +-- +--@code +-- if bloom_filter:set(item)) then +-- print("this data not exists, set ok!") +-- else +-- -- note: maybe false positives +-- print("this data have been existed, set failed!") +-- end +--@endcode +-- +function _instance:set(item) + + -- ensure opened + local ok, errors = self:_ensure_opened() + if not ok then + return false, errors + end + + -- do set + return bloom_filter._set(self:cdata(), item) +end + +-- get the bloom filter data item +-- +--@code +-- if bloom_filter:get(item)) then +-- -- note: maybe false positives +-- print("this data have been existed, get ok!") +-- else +-- print("this data not exists, get failed!") +-- end +--@endcode +-- +function _instance:get(item) + + -- ensure opened + local ok, errors = self:_ensure_opened() + if not ok then + return false, errors + end + + -- do get + return bloom_filter._get(self:cdata(), item) +end + +-- ensure it is opened +function _instance:_ensure_opened() + if not self:cdata() then + return false, string.format("%s: has been closed!", self) + end + return true +end + +-- tostring(bloom_filter) +function _instance:__tostring() + return string.format("<bloom_filter: %s>", self:cdata()) +end + +-- gc(bloom_filter) +function _instance:__gc() + if self:cdata() and bloom_filter._close(self:cdata()) then + self._HANDLE = nil + end +end + +-- new a bloom filter, e.g. {probability = 0.001} +function bloom_filter.new(opt) + opt = opt or {} + local probability = opt.probability or 0.001 + local maps = { + [0.1] = bloom_filter.PROBABILITY_0_1 + [0.01] = bloom_filter.PROBABILITY_0_01 + [0.001] = bloom_filter.PROBABILITY_0_001 + [0.0001] = bloom_filter.PROBABILITY_0_0001 + [0.00001] = bloom_filter.PROBABILITY_0_00001 + [0.000001] = bloom_filter.PROBABILITY_0_000001 + } + probability = assert(maps[probability], "invalid probability(%f)", probability) + local handle, errors = bloom_filter._open(probability) + if handle then + return _instance.new(handle) + else + return nil, errors or "failed to open a bloom filter!" + end +end + +-- return module: bloom_filter +return bloom_filter diff --git a/xmake/core/compress/lz4.lua b/xmake/core/compress/lz4.lua index 6a5c97be0..2e605993a 100644 --- a/xmake/core/compress/lz4.lua +++ b/xmake/core/compress/lz4.lua @@ -136,7 +136,7 @@ function _cstream:write(data, opt) return write, errors end --- ensure the socket is opened +-- ensure it is opened function _cstream:_ensure_opened() if not self:cdata() then return false, string.format("%s: has been closed!", self) @@ -247,7 +247,7 @@ function _dstream:write(data, opt) return write, errors end --- ensure the socket is opened +-- ensure it is opened function _dstream:_ensure_opened() if not self:cdata() then return false, string.format("%s: has been closed!", self) |
