Current section

Files

Jump to
bitgraph src bit_vector.erl
Raw

src/bit_vector.erl

-module(bit_vector).
-export([new/1, get/2, set/2, clear/2, flip/2, print/1]).
% Allocate atomics to contain the data + 2 bytes for min and max
new(Size) ->
Words = (Size + 63) div 64,
Atomics = atomics:new(Words + 1, [{signed, false}]),
atomics:put(Atomics, Words + 1, 0), %% Set 'min_max' to lowest possible
{?MODULE, Atomics}.
get({?MODULE, Aref}, Bix) ->
Wix = (Bix div 64) + 1,
Mask = (1 bsl (Bix rem 64)),
case atomics:get(Aref, Wix) band Mask of
0 -> 0;
Mask -> 1
end.
set({?MODULE, Aref}, Bix) ->
Mask = (1 bsl (Bix rem 64)),
update(Aref, Bix, fun(Word) -> Word bor Mask end).
clear({?MODULE, Aref}, Bix) ->
Mask = bnot (1 bsl (Bix rem 64)),
update(Aref, Bix, fun(Word) -> Word band Mask end).
flip({?MODULE, Aref}, Bix) ->
Mask = (1 bsl (Bix rem 64)),
update(Aref, Bix, fun(Word) -> Word bxor Mask end).
print({?MODULE, Aref} = BV) ->
#{size := Size} = atomics:info(Aref),
print(BV, Size).
print(BV, 0) ->
io:format("~B~n",[get(BV, 0)]);
print(BV, Slot) ->
io:format("~B",[get(BV, Slot)]),
print(BV, Slot-1).
update(Aref, Bix, Fun) ->
Wix = (Bix div 64) + 1,
update_loop(Aref, Wix, Fun, atomics:get(Aref, Wix)).
update_loop(Aref, Wix, Fun, Current) ->
case atomics:compare_exchange(Aref, Wix, Current, Fun(Current)) of
ok ->
ok;
Was ->
update_loop(Aref, Wix, Fun, Was)
end.