From e1fddd663306e44235d6057e27cc3c160b01517f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20S=C3=B8e=20S=C3=B8rensen?= Date: Thu, 27 Sep 2012 13:17:32 +0200 Subject: [PATCH] Bloom filter: make "don't set if already set" logic more fine-grained. This results in a minor "bloom add" performance gain of ~10%. --- src/hanoidb_bloom.erl | 14 +++++--------- src/hanoidb_dense_bitmap.erl | 6 +++++- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/hanoidb_bloom.erl b/src/hanoidb_bloom.erl index c5d357c..ea88d39 100644 --- a/src/hanoidb_bloom.erl +++ b/src/hanoidb_bloom.erl @@ -148,10 +148,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 %% @@ -175,10 +172,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) -> @@ -226,7 +220,9 @@ bitarray_set(I, A) -> 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. bitarray_get(I, A) -> AI = I div ?W, diff --git a/src/hanoidb_dense_bitmap.erl b/src/hanoidb_dense_bitmap.erl index 300ccf8..1f45218 100644 --- a/src/hanoidb_dense_bitmap.erl +++ b/src/hanoidb_dense_bitmap.erl @@ -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}) ->