defmodule Queue do
use GenServer
defstruct container: nil, capacity: nil, count: nil
def start(k) do
GenServer.start(__MODULE__, k, name: __MODULE__)
end
def reset(k), do: GenServer.call(__MODULE__, {:reset, k})
@impl GenServer
def init(k) do
{:ok, %__MODULE__{container: :queue.new(), capacity: k, count: 0}}
end
@impl GenServer
def handle_call(:front, _, %__MODULE__{count: 0} = state),
do: {:reply, -1, state}
@impl GenServer
def handle_call(:front, _, %__MODULE__{container: q} = state),
do: {:reply, :queue.get(q), state}
@impl GenServer
def handle_call(:rear, _, %__MODULE__{count: 0} = state),
do: {:reply, -1, state}
@impl GenServer
def handle_call(:rear, _, %__MODULE__{container: q} = state),
do: {:reply, :queue.get_r(q), state}
@impl GenServer
def handle_call({:in, _}, _, %__MODULE__{capacity: cap, count: cap} = state),
do: {:reply, false, state}
@impl GenServer
def handle_call({:in, item}, _, %__MODULE__{container: q, count: c} = state),
do: {:reply, true, %__MODULE__{state | container: :queue.in(item, q), count: c + 1}}
@impl GenServer
def handle_call(:drop, _, %__MODULE__{count: 0} = state),
do: {:reply, false, state}
@impl GenServer
def handle_call(:drop, _, %__MODULE__{container: q, count: c} = state),
do: {:reply, true, %__MODULE__{state | container: :queue.drop(q), count: c - 1}}
@impl GenServer
def handle_call(:is_empty, _, %__MODULE__{} = state),
do: {:reply, state.count == 0, state}
@impl GenServer
def handle_call(:is_full, _, %__MODULE__{} = state),
do: {:reply, state.count == state.capacity, state}
@impl GenServer
def handle_call({:reset, k}, _, _),
do: {:reply, :ok, %__MODULE__{container: :queue.new(), count: 0, capacity: k}}
end
defmodule MyCircularQueue do
def init_(k) do
case GenServer.whereis(Queue) do
nil ->
Queue.start(k)
_ ->
Queue.reset(k)
end
end
def en_queue(value), do: GenServer.call(Queue, {:in, value})
def de_queue(), do: GenServer.call(Queue, :drop)
def front(), do: GenServer.call(Queue, :front)
def rear(), do: GenServer.call(Queue, :rear)
def is_empty(), do: GenServer.call(Queue, :is_empty)
def is_full(), do: GenServer.call(Queue, :is_full)
end