defmodule BoundedMapBuffer do
@moduledoc """
Documentation for `BoundedMapBuffer`.
"""
defstruct [
:data_map,
:current_position,
:length
]
def new(size) do
%BoundedMapBuffer{
data_map: (for i <- 0..(size - 1), into: %{}, do: {i, nil}),
current_position: 0,
length: size
}
end
def push(buffer = %BoundedMapBuffer{}, obj) do
%BoundedMapBuffer{
data_map: Map.put(buffer.data_map, buffer.current_position, obj),
current_position: rem(buffer.current_position + 1, buffer.length),
length: buffer.length
}
end
def push_all(buffer = %BoundedMapBuffer{}, []) do
buffer
end
def push_all(buffer = %BoundedMapBuffer{}, [first | rest]) do
push_all(buffer |> BoundedMapBuffer.push(first), rest)
end
def peek(buffer = %BoundedMapBuffer{}) when buffer.current_position == 0 do
buffer.data_map[buffer.length - 1]
end
def peek(buffer = %BoundedMapBuffer{}) do
buffer.data_map[buffer.current_position - 1]
end
defp fix_index(index, size) when index < size do
index
end
defp fix_index(index, size) do
index - size
end
def to_list(buffer = %BoundedMapBuffer{}) do
for i <- buffer.current_position..(buffer.current_position + buffer.length - 1) do
fixed_i = fix_index(i, buffer.length)
Map.get(buffer.data_map, fixed_i)
end
end
end