Packages
inplace
0.6.2
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
@doc """
Initializes array of size `size`.
`initial_value` will be used to set up the initial value for array elements.
"""
def new(size, initial_value \\ @null)
def new(size, 0) do
:atomics.new(size, signed: true)
end
def new(size, initial_value) do
new(size, 0)
|> tap(fn ref ->
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
updated_value = update_fun.(current)
if updated_value do
case :atomics.compare_exchange(array, idx, current, updated_value) do
:ok ->
updated_value
altered ->
update_loop(array, idx, altered, update_fun)
end
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