Term container supporting `push(term)` and `get_last_100()`

Erlang’s built-in :queue should work fine for this, I’d think. You can of course use a library, but I’d likely implement this myself to have fewer deps.

To be clear, do you only ever want to save the last N entries, i.e. the oldest entry is dropped when N+1 entry is pushed? If so, you could use a {queue, current_len, max_len} tuple and a push/2 and pop_n/2 that implements your requirements.

Edit: sketching this out

def new(max_len) do
  {:queue.new(), 0, max_len}
end

def push({q, max, max}, element) do
  # at max len so drop element at head of queue
  q = :queue.drop(q)
  {:queue.in(element, q), max, max}
end

def push({q, len, max}, element) do
  {:queue.in(element, q), len + 1, max}
end

def pop_n({q, len, max}, n) when n >= len do
  {:queue.to_list(q), new(max)}
end

def pop_n({q, len, max}, n) do
  # exercise for reader ;)
  # could do recursive pop or split
  # https://www.erlang.org/doc/man/queue.html#split-2
end
2 Likes