Packages
inplace
0.4.1
0.7.12
0.7.11
0.7.10
0.7.9
0.7.8
0.7.7
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.8
0.6.7
0.6.6
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.3
0.3.2
0.3.1
0.3.0
0.2.3
0.2.2
0.2.1
0.2.0
0.1.9
0.1.8
0.1.7
0.1.6
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
Mutable data structures
Current section
Files
Jump to
Current section
Files
lib/adt/array.ex
defmodule InPlace.Array do
import Bitwise
@null (1 <<< 63) - 1
def new(size, initial_value \\ @null) do
:atomics.new(size, signed: true)
|> tap(fn ref ->
initial_value != 0 &&
Enum.each(1..size, fn idx -> put(ref, idx, initial_value) end)
end)
end
## Get element by (1-based) index
def get(array, idx) when is_integer(idx) do
case :atomics.get(array, idx) do
@null -> nil
val -> val
end
end
def put(array, idx, nil) when is_integer(idx) do
delete(array, idx)
end
def put(array, idx, value) when is_integer(idx) and is_integer(value) do
:atomics.put(array, idx, value || @null)
end
def delete(array, idx) do
put(array, idx, @null)
end
def update(array, idx, update_fun) do
update_loop(array, idx, get(array, idx), update_fun)
end
defp update_loop(array, idx, current, update_fun) do
case :atomics.compare_exchange(array, idx, current, update_fun.(current)) do
:ok ->
:ok
altered ->
update_loop(array, idx, altered, update_fun)
end
end
def swap(array, idx1, idx2) do
val1 = get(array, idx1)
val2 = get(array, idx2)
put(array, idx1, val2)
put(array, idx2, val1)
end
def to_list(array) do
Enum.map(1..size(array), fn idx -> :atomics.get(array, idx) end)
end
def reduce(array, initial_value, reducer \\ fn el, acc -> [el | acc] end)
when is_function(reducer) do
Enum.reduce(1..size(array), initial_value, fn idx, acc ->
reducer.(:atomics.get(array, idx), acc)
end)
end
def size(array) do
:atomics.info(array)[:size]
end
def null() do
@null
end
def inf() do
null() - 1
end
def negative_inf() do
-inf()
end
end