I think I have need of an vector of fixed size, where push!
ing a new value basically shifts everything down, so that the first element gets dropped, the thing at index 2 goes to index 1, etc. The use-case is that I'm writing a wrapper for a web API that has a rate-limit of 5 requests / sec. I'm thinking of basically storing the time of the last 5 requests, and if the first one (earliest
) is < 1 sec ago, pause for long enough to make it > 1 sec ago, then do the new request.
I have an idea of how to do this with a mutable struct
that just stores the vector and an index that cycles 1-5 , but I'm wondering if there's some data structure like this that already exists / has a julia implementation.
I think this is called a circular buffer. Have a look at DataStructures.jl which provides a CircularBuffer
type.
https://juliacollections.github.io/DataStructures.jl/latest/circ_buffer/
Ahh, exactly!
Though thinking through it, I think given my specific use case, the custom solution is maybe lighter weight. Here's what I have:
mutable struct Timer
idx::Int
last5::Vector{DateTime}
Timer() = new(1, zeros(DateTime, 5))
end
function _ratelimit!(t::Timer)
n = now()
e = t.last5[t.idx]
rl = n - e
if rl < Millisecond(1000)
sleep(Millisecond(1000) - rl)
n = now()
end
t.last5[t.idx] = n
t.idx = 1 + (t.idx % 5)
end
Last updated: Nov 06 2024 at 04:40 UTC