Fixes and better tests.

This commit is contained in:
Gregory Burd 2012-06-20 14:04:05 +01:00
parent d30133a87a
commit dd05cffa7a
8 changed files with 75 additions and 142 deletions

View file

@ -80,7 +80,7 @@ proper-compile: compile-proper
eunit: eunit-compile
@echo "eunit testing: $(RELPKG) ..."
$(REBAR) eunit recursive=false
$(REBAR) eunit skip_deps=true
eqc: eqc-compile
@echo "eqc testing: $(RELPKG) ... not implemented yet"

View file

@ -2,9 +2,13 @@
{cover_enabled, true}.
{clean_files, ["*.eunit", "ebin/*.beam"]}.
{eunit_opts, [verbose, {report, {eunit_surefire, [{dir, "."}]}}]}.
{eunit_opts, [verbose,
{report, {eunit_surefire, [{dir, "."},
{parse_transform, lager_transform}
]}}]}.
{deps, [ {edown, "0.3.*", {git, "git://github.com/esl/edown.git", {branch, "master"}}}
, {lager, ".*", {git, "git://github.com/basho/lager", {branch, "master"}}}
, {asciiedoc, "0.1.*", {git, "git://github.com/norton/asciiedoc.git", {branch, "master"}}}
, {triq, ".*", {git, "git://github.com/krestenkrab/triq.git", {branch, "master"}}}
]}.

View file

@ -37,7 +37,7 @@ new(N, E) when N > 0, is_float(E), E > 0, E =< 1 ->
%% @doc Creates a new empty Bloom filter from an existing one.
-spec clear(#bloom{}) -> #bloom{}.
clear(#bloom{bitmap=Bitmap} = B) ->
B#bloom{bitmap = <<0:(erlang:bit_size(Bitmap))>>, n=0}.
B#bloom{bitmap = <<0:(erlang:bit_size(Bitmap))>>, n=0, keys=0}.
%% @doc Returns the number of elements encoded into this Bloom filter.
-spec count(#bloom{}) -> non_neg_integer().

View file

@ -1,12 +1,20 @@
{application, bloomerl,
[
{description, "Bloom filters"},
{vsn, "1.0.0"},
{registered, []},
{applications, [
kernel,
stdlib
]},
{applications, [kernel, stdlib ]},
{mod, {bloomerl_app, []}},
{env, []}
]}.
{env, [
{lager, [
{handlers, [
{lager_console_backend, info},
{lager_file_backend, [
{"error.log", error, 10485760, "$D0", 5},
{"console.log", info, 10485760, "$D0", 5}
]}
]}
]}
]}
]}.

View file

@ -1,88 +0,0 @@
%% -------------------------------------------------------------------
%%
%% Copyright (c) 2010 Basho Technologies, Inc. All Rights Reserved.
%%
%% This file is provided to you 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.
%%
%% -------------------------------------------------------------------
%% This module in bloomerl serves to provide drop-in compatibility with
%% the ebloom module.
-module(ebloom).
-author('Greg Burd <greg@burd.me>').
-export([new/3,
insert/2,
contains/2,
clear/1,
size/1,
elements/1,
effective_fpp/1,
intersect/2,
union/2,
difference/2,
serialize/1,
deserialize/1]).
-spec new(integer(), float(), integer()) -> {ok, reference()}.
new(Count, FalseProb, _Seed) ->
{ok, bloom:new(Count, FalseProb)}.
-spec insert(reference(), binary()) -> ok.
insert(Ref, Bin) ->
bloom:add_element(Bin, Ref),
ok.
-spec contains(reference(), binary()) -> true | false.
contains(Ref, Bin) ->
bloom:is_element(Bin, Ref).
-spec clear(reference()) -> ok.
clear(Ref) ->
bloom:clear(Ref).
-spec size(reference()) -> integer().
size(Ref) ->
bloom:filter_size(Ref).
-spec elements(reference()) -> integer().
elements(Ref) ->
bloom:count(Ref).
-spec effective_fpp(reference()) -> float().
effective_fpp(_Ref) ->
throw(not_yet_implemented).
-spec intersect(reference(), reference()) -> ok.
intersect(_Ref, _OtherRef) ->
throw(not_yet_implemented).
-spec union(reference(), reference()) -> ok.
union(_Ref, _OtherRef) ->
throw(not_yet_implemented).
-spec difference(reference(), reference()) -> ok.
difference(_Ref, _OtherRef) ->
throw(not_yet_implemented).
-spec serialize(reference()) -> binary().
serialize(Ref) ->
erlang:term_to_binary(Ref).
-spec deserialize(binary()) -> {ok, reference()}.
deserialize(Bin) ->
erlang:binary_to_term(Bin).

View file

@ -1,7 +0,0 @@
basic_test() ->
{ok, Ref} = new(5, 0.01, 123),
0 = elements(Ref),
insert(Ref, <<"abcdef">>),
true = contains(Ref, <<"abcdef">>),
false = contains(Ref, <<"zzzzzz">>).

54
test/bloom_tests.erl Normal file
View file

@ -0,0 +1,54 @@
%% @hidden
-module(bloom_tests).
-compile(export_all).
-include_lib("eunit/include/eunit.hrl").
all_my_test_() ->
[ {"Should create a bloom filter", fun should_create_a_bloom_filter/0}
, {"Should be sized correctly", fun should_be_sized_correctly/0}
, {"Should contain one element", fun should_contain_one_element/0}
].
should_create_a_bloom_filter() ->
Bloom = bloom:new(5, 0.001),
true = bloom:is_bloom(Bloom),
false = bloom:is_bloom({foo}).
should_be_sized_correctly() ->
Bloom1 = bloom:new(5, 0.1),
32 = bloom:filter_size(Bloom1),
Bloom2 = bloom:new(5, 0.01),
48 = bloom:filter_size(Bloom2),
Bloom3 = bloom:new(5), % default is 0.001
72 = bloom:filter_size(Bloom3),
Bloom4 = bloom:new(5, 0.0001),
96 = bloom:filter_size(Bloom4).
should_contain_one_element() ->
Bloom = bloom:new(5, 0.01),
0 = bloom:count(Bloom),
Bloom1 = bloom:add_element(<<"abcdef">>, Bloom),
Bloom1 = bloom:add_element(<<"abcdef">>, Bloom),
1 = bloom:count(Bloom1),
true = bloom:is_element(<<"abcdef">>, Bloom1),
false = bloom:is_element(<<"zzzzzz">>, Bloom1),
Bloom2 = bloom:clear(Bloom1),
0 = bloom:count(Bloom2),
false = bloom:is_element(<<"abcdef">>, Bloom2),
false = bloom:is_element(<<"zzzzzz">>, Bloom2).
%% Helper functions
%% fold_lines(FileName, Fun) ->
%% {ok, Device} = file:open(FileName, [read]),
%% fold_over_lines(Device, Fun).
%% fold_over_lines(Device, Fun) ->
%% case io:get_line(Device, "") of
%% eof ->
%% file:close(Device);
%% Line ->
%% Fun(Line), fold_over_lines(Device, Fun)
%% end.

View file

@ -1,38 +0,0 @@
basic_test() ->
{ok, Ref} = new(5, 0.01, 123),
0 = elements(Ref),
insert(Ref, <<"abcdef">>),
true = contains(Ref, <<"abcdef">>),
false = contains(Ref, <<"zzzzzz">>).
%% union_test() ->
%% {ok, Ref} = new(5, 0.01, 123),
%% {ok, Ref2} = new(5, 0.01, 123),
%% insert(Ref, <<"abcdef">>),
%% false = contains(Ref2, <<"abcdef">>),
%% union(Ref2, Ref),
%% true = contains(Ref2, <<"abcdef">>).
serialize_test() ->
{ok, Ref} = new(5, 0.01, 123),
{ok, Ref2} = new(5, 0.01, 123),
Bin = serialize(Ref),
Bin2 = serialize(Ref2),
true = (Bin =:= Bin2),
insert(Ref, <<"abcdef">>),
Bin3 = serialize(Ref),
{ok, Ref3} = deserialize(Bin3),
true = contains(Ref3, <<"abcdef">>),
false = contains(Ref3, <<"rstuvw">>).
clear_test() ->
{ok, Ref} = new(5, 0.01, 123),
0 = elements(Ref),
insert(Ref, <<"1">>),
insert(Ref, <<"2">>),
insert(Ref, <<"3">>),
3 = elements(Ref),
clear(Ref),
0 = elements(Ref),
false = contains(Ref, <<"1">>).