Prepare enqueue API
As for today we have bulk operations which reduce synchronization costs in average but it has high latency as we should move many elements at once. And I think API like queue.prepare_enqueue(max_count) -> output_iterator, "write to output iterator many times without sync", std::move(output_iterator).commit() would distribute moving values into many write calls.
The issue describes only enqueue, because underlying queues are single-producer ones, so it should be much easier than multiple-consumer synchronization
While possible in theory, this is not easy to implement. The elements are not necessarily contiguous if multiple blocks are involved. Additionally, the uncommitted state would need to be tracked in order to prevent other interleaved calls to enqueue from succeeding.
You can already pass in a custom iterator to enqueue_bulk allowing items to be generated on the fly. Does this fit your use case?
I don't see a big problem with non contiguous elements as iterator can create new blocks. As for preventing other calls the best solution I think would be to restrict this functionality to producer tokens and when we call PrepareWrite(Token&&) we will move our token there and Commit->Token&& method will move it back to us. So nobody will be able to write to that queue
Btw, passing iterator to enqueue bulk does not prevent O(N) element moves at once. So it does not fit :(
Btw, passing iterator to enqueue bulk does not prevent O(N) element moves at once. So it does not fit :(
Can you elaborate? I had in mind something like:
ConcurrentQueue<T> q;
struct Generator {
T buildNextValue() { return T(); /* TODO */ }
T&& operator*() { T x = buildNextValue(); return std::move(x); }
Generator& operator++() { return *this; }
};
// ...
Generator g;
q.enqueue_bulk(g, 123);