DataStructures.jl icon indicating copy to clipboard operation
DataStructures.jl copied to clipboard

Implement constructor for Deque from iterable

Open jordancluts opened this issue 3 years ago • 2 comments

At present a Deque (and Stack/Queue) can only be created empty.

A constructor method should be added to enable the creation of a Deque from an iterable such as an array. At present Deque([1,2,3]) errors.

A few issues to discuss

  • What Deque Block Size to choose by default when given an array/iterable?
  • Should a user be able to pass both an array and a blocksize? (at the moment Deque(x::Int) creates an empty Deque with block size of x). We could add a Deque(array,blocksize) method or similar to allow specification.

jordancluts avatar Apr 27 '21 18:04 jordancluts

I think I think we should have the 2 arg one where you pass the blocksize. and the 1 arg version that just takes it iterator, and the default blocksize should equal to the length of the iterator. which we probably need to get by collecting it and then taking the length (since notall itrerators have length, but we are going to collect them anyway)

Something like:

Deque(x::Vector, blocksize=length(x)) =  # Main constructor
Deque(iter, blocksize) = Deque(vec(collect(iter)), blocksize)
Deque(iter) = Deque(vec(collect(iter)))

oxinabox avatar Apr 28 '21 14:04 oxinabox

I completely agree. There may be some argument for making the initial block size equal to some larger fraction of the initial vector. This prevents another allocation on the first push!. Alternatively, the "unrolled linked list" that the Deque is currently built upon is designed for cache efficiency so choosing a block size related to cache sizes would be optimal from a performance perspective. Doing so automatically would require querying the CPU for info (l3 cache sizes and cache row sizes) when the package is loaded and then setting a variable to use in construction accordingly. That however is a much bigger task.

I was messing around with various things and arrived at basically the same solution as you but I decided to start with CircularBuffer as I thought it's implementation was good and it's a more basic data structure. Other data structures can then be updated to match and/or be built upon the more fundamental piece. Expect the PR for CircularBuffer soon.

jordancluts avatar Apr 28 '21 14:04 jordancluts