Merge pull request #18 from eriksoe/bloom-sparse-representation

Bloom filter: make "don't set if already set" logic more fine-grained.
This commit is contained in:
Kresten Krab Thorup 2012-09-27 04:53:44 -07:00
commit e3689c3d87
2 changed files with 10 additions and 10 deletions

View file

@ -150,10 +150,7 @@ masked_pair(Mask, X, Y) -> {X band Mask, Y band Mask}.
all_set(_Mask, _I1, _I, []) -> true;
all_set(Mask, I1, I, [H|T]) ->
case bitmask_get(I, H) of
true -> all_set(Mask, I1, (I+I1) band Mask, T);
false -> false
end.
bitmask_get(I, H) andalso all_set(Mask, I1, (I+I1) band Mask, T).
%% Adds element to set
%%
@ -177,10 +174,7 @@ add(Elem, #sbf{size=Size, r=R, s=S, b=[H|T]=Bs}=Sbf) ->
hash_add(Hashes, #bloom{mb=Mb, a=A, size=Size} = B) ->
Mask = 1 bsl Mb -1,
{I1, I0} = make_indexes(Mask, Hashes),
case all_set(Mask, I1, I0, A) of
true -> B;
false -> B#bloom{size=Size+1, a=set_bits(Mask, I1, I0, A, [])}
end.
B#bloom{size=Size+1, a=set_bits(Mask, I1, I0, A, [])}.
set_bits(_Mask, _I1, _I, [], Acc) -> lists:reverse(Acc);
set_bits(Mask, I1, I, [H|T], Acc) ->
@ -236,7 +230,9 @@ bitarray_set(I, A1) ->
AI = I div ?W,
V = array:get(AI, A),
V1 = V bor (1 bsl (I rem ?W)),
array:set(AI, V1, A).
if V =:= V1 -> A; % The bit is already set
true -> array:set(AI, V1, A)
end.
-spec bitarray_get( non_neg_integer(), array() ) -> boolean().
bitarray_get(I, A) ->

View file

@ -18,7 +18,11 @@ set(I, {dense_bitmap_ets, _,_, Tab}=DBM) ->
BitInCell = I rem ?BITS_PER_CELL,
Old = ets:lookup_element(Tab, ?REPR_NAME, Cell),
New = Old bor (1 bsl BitInCell),
ets:update_element(Tab, ?REPR_NAME, {Cell,New}),
if New =:= Old ->
ok; % The bit is already set
true ->
ets:update_element(Tab, ?REPR_NAME, {Cell,New})
end,
DBM.
build({dense_bitmap_ets, _, _, Tab}) ->