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, []) -> true;
all_set(Mask, I1, I, [H|T]) -> all_set(Mask, I1, I, [H|T]) ->
case bitmask_get(I, H) of bitmask_get(I, H) andalso all_set(Mask, I1, (I+I1) band Mask, T).
true -> all_set(Mask, I1, (I+I1) band Mask, T);
false -> false
end.
%% Adds element to set %% 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) -> hash_add(Hashes, #bloom{mb=Mb, a=A, size=Size} = B) ->
Mask = 1 bsl Mb -1, Mask = 1 bsl Mb -1,
{I1, I0} = make_indexes(Mask, Hashes), {I1, I0} = make_indexes(Mask, Hashes),
case all_set(Mask, I1, I0, A) of B#bloom{size=Size+1, a=set_bits(Mask, I1, I0, A, [])}.
true -> B;
false -> B#bloom{size=Size+1, a=set_bits(Mask, I1, I0, A, [])}
end.
set_bits(_Mask, _I1, _I, [], Acc) -> lists:reverse(Acc); set_bits(_Mask, _I1, _I, [], Acc) -> lists:reverse(Acc);
set_bits(Mask, I1, I, [H|T], Acc) -> set_bits(Mask, I1, I, [H|T], Acc) ->
@ -236,7 +230,9 @@ bitarray_set(I, A1) ->
AI = I div ?W, AI = I div ?W,
V = array:get(AI, A), V = array:get(AI, A),
V1 = V bor (1 bsl (I rem ?W)), 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(). -spec bitarray_get( non_neg_integer(), array() ) -> boolean().
bitarray_get(I, A) -> bitarray_get(I, A) ->

View file

@ -18,7 +18,11 @@ set(I, {dense_bitmap_ets, _,_, Tab}=DBM) ->
BitInCell = I rem ?BITS_PER_CELL, BitInCell = I rem ?BITS_PER_CELL,
Old = ets:lookup_element(Tab, ?REPR_NAME, Cell), Old = ets:lookup_element(Tab, ?REPR_NAME, Cell),
New = Old bor (1 bsl BitInCell), 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. DBM.
build({dense_bitmap_ets, _, _, Tab}) -> build({dense_bitmap_ets, _, _, Tab}) ->