Current section

Files

Jump to
smppex lib smppex pdu_storage.ex
Raw

lib/smppex/pdu_storage.ex

defmodule SMPPEX.PduStorage do
@moduledoc false
alias :ets, as: ETS
alias SMPPEX.Compat
alias SMPPEX.PduStorage
alias SMPPEX.Pdu
defstruct [
:by_sequence_number
]
@type t :: %PduStorage{}
@spec new :: %PduStorage{}
def new do
%PduStorage{
by_sequence_number: ETS.new(:pdu_storage_by_sequence_number, [:set])
}
end
@spec store(t, Pdu.t(), non_neg_integer) :: boolean
def store(storage, %Pdu{} = pdu, expire_time) do
sequence_number = Pdu.sequence_number(pdu)
ETS.insert_new(storage.by_sequence_number, {sequence_number, {expire_time, pdu}})
end
@spec fetch(t, non_neg_integer) :: [Pdu.t()]
def fetch(storage, sequence_number) do
case Compat.ets_take(storage.by_sequence_number, sequence_number) do
[{^sequence_number, {_expire_time, pdu}}] ->
[pdu]
[] ->
[]
end
end
@spec fetch_expired(t, non_neg_integer) :: [Pdu.t()]
def fetch_expired(storage, expire_time) do
expired =
ETS.select(storage.by_sequence_number, [
{{:_, {:"$1", :"$2"}}, [{:<, :"$1", expire_time}], [:"$2"]}
])
expired_count = length(expired)
^expired_count =
ETS.select_delete(storage.by_sequence_number, [
{{:_, {:"$1", :"$2"}}, [{:<, :"$1", expire_time}], [true]}
])
expired
end
@spec fetch_all(t) :: [Pdu.t()]
def fetch_all(storage) do
pdus = for {_sn, {_ex, pdu}} <- ETS.tab2list(storage.by_sequence_number), do: pdu
ETS.delete_all_objects(storage.by_sequence_number)
pdus
end
end