TBB concurrent_queue - accessing first element without popping it out - concurrency

I am using TBB concurrent_queue class. It meets my needs except that I need to access the first element before popping it out of the queue. As I understand from the document, one can't access first element or can't insert at the front like std:deque.
Any idea how to achieve this while maintaining concurrency as far as possible.

Related

Boost heap handle to top element

I have an algorithm which essentially takes elements of type T, pushes them to a priority_queue, and then takes the top element of the queue, modifies it, updates the heap, takes the (possibly new) top element, and so on.
I'd like to try the Boost heap library to replace std::priority_queue to avoid having to update by a pop followed by a push of the same element. However, I cannot seem to find a way to access a handle to the top of the queue, to update it.
Specifically there seems to be only two ways to get a handle to an element:
s_handle_from_iterator(it). However, the iterator returned by begin() is not necessarily the top of the stack, and this method does not take ordered_iterator, so it seems I'm out of luck?
push(elem) returns the handle. However, using that seems to mean that I have to store the handle somewhere, probably in the element itself, which seems like a waste of space (and time, when handling the elements).
Is there a better way?
Note that for a slightly different use case (iterating the whole heap in order) this answer seems to suggest that there really isn't a better way...

Can I access elements of a Priority Que using an iterator?

Vectors and Linked Lists
Vectors are stored in memory serially, and therefore any element may be accessed using the operator[], just as in an array.
A linked list contains elements which may not be stored continuously in memory, and therefore a random element must be accessed by following pointers, using an iterator.
(You probably already knew this.)
Advantage of Priority Que
Recently I discovered the 'priority queue', which works kind of like a stack, but elements are push()-ed into the container, and this function places them in an order according to comparisons made with the operator<, I believe.
This suits me perfectly, as I am testing for events and placing them in the queue according to the time remaining until they occur. The queue automatically sorts them for me as I push() and pop() elements. (Popping does not affect the order.) I can write an operator< so this isn't a problem.
Issues I have not been able to resolve
There are three things which I need to be able to do with this event queue:
1:) Search the event queue for an item. I assume this can be done with an algorithm in the standard library? For example, 'find'? If not I can implement one myself, provided I can do point 2. (See below)
2:) Iterate over the queue. I think the default underlying container is std::vector... Is there a way to access random elements within the underlying vector? What if I choose to use std::deque instead? I need to do this to modify certain event parameters. (Events are placed in the queue.) As an example, I may need to process an event and then subtract a constant amount of time from each remaining event's 'time_to_event' parameter. I suspect this cannot be done due to this question.
3:) Remove an element from the queue. Sometimes when processing events, other events become invalidated, and therefore need to be removed.
Can points 1-3 be done? All the information I have on std::priority_queue has come from cplusplus.com, and so my default answer would be "no", there is no way to do any of these things. If I can't do all three things, then I guess I will have to write my own Priority Queue wrapper. (Oh boring)
No, you can't iterate over items in an std::priority_queue. All it supports is inserting items, and removing the highest priority item.
When you want more flexibility, you probably want to use std::make_heap to build the heap structure into your container, std::push_heap to add an item, and std::pop_heap to remove an item.
Since these are algorithms you apply to a container, you can still use the container's iterators as you see fit. Depending on how you modify the data in the heap, you may need to re-build the heap afterwards -- if you modify it in a way that the heap property no longer applies. You can test that with std::is_heap if you have any question.
Aside: many of us find http://www.cppreference.com more useful and accurate than the site you've linked.
Take a look at Boost.Heap. It looks like it addresses at least two of your issues (iteration and mutability).

Why does std::queue not have operator[]?

The std::queue is implemented with a deque by default. std::deque has the subscript operator, operator[], and is probably implemented with arrays. So why doesn't std::queue have operator[]?
I realize you could have a queue with a list as the underlying container. (std::queue<int, std::list<int>>.) But even if that would make the subscript operator slow, is that really a good reason not to include it? That's the only reason I can think of that it is not included.
Because the definition of queue doesn't support such interface. Queue is a FIFO data structure which means First In First Out. Queue supports enqueue and dequeue operations.
Imagine of queue as pipe : you insert data into one end and from the other end you take it out - one by one. Inserting data is called enqueue and taking them out is called dequeue. The C++ standard library has std::queue which defines both these operations: push() is the name of enqueue operation, and dequeue operation has been splitted into two steps namely front() followed by pop(). The rationale why dequeue has been split into two steps is to give strong exception guarantee1.
Wikipedia explains this briefly,
A queue is a particular kind of collection in which the entities in the collection are kept in order and the principal (or only) operations on the collection are the addition of entities to the rear terminal position and removal of entities from the front terminal position. This makes the queue a First-In-First-Out (FIFO) data structure. In a FIFO data structure, the first element added to the queue will be the first one to be removed. This is equivalent to the requirement that once an element is added, all elements that were added before have to be removed before the new element can be invoked. A queue is an example of a linear data structure.
1. If you want to know how exacly it gives strong exception guarantee, then you can start another topic, because it's very long story, and requires lots of patience to understand it properly. I would suggest you to read Exceptional C++ by Herb Sutter for this.
It's a concept issue. In a queue, you add to the back and take from the front, not from the middle
The reason not to include it because a queue is a data structure with enqueue and dequeue operations, not random access. std::queue exists to adapt an existing container into a queue interface, so it only provides the queue interface.
If you want to use [] then use a deque with push_front and back/pop_back not a queue.
Why a double ended queue has it but not a queue doesn't make sense to me either.

Good container for insert-in-order? C++

Hi I was wondering what the best container for inserting elements in order in? A map I think is unnecessary since I am just going to be accessing the element at the front, popping it and then inserting more elements (I'm implementing a pathfinding algorithm (Dijkstra) with weights)
I could probably have used a list and inserted in order myself, but the inability to bisect (because you start accessing at the front or back) would be hindering to performance.
If you need only access the front and back, std::deque (double-ended queue) fits the bill perfectly.
However, for a Dijkstra algorithm, don't you need a priority queue instead?
If you are using C++ there is a std::priority_queue container adapter in the <queue> header file.

delete element from priority queue in c++ stl

Is i have a priority queue with declaration
priority_queue<<Node>,vector<Node>,myComp> openQ
i am inserting node objects into it. but at some time i have to delete the element from it. (not to remove the top element)
Currently to delete it i am popping the element and putting it in array. if the top most element is desired then expect it i push other elements in array.
This is like linear search and delete. I know its not efficient and i am looking for some better ways
priority_queue class is designed for using as queue with priorities. And it designed to remove elements with pop function. If you want to get different behavior you should use different class. For instance, std::map.
If you're ready to manually control a consistence of the queue you may take a look on std::make_heap. It's easy to create a max-heap with it. But in this case you need to manually rebuild a queue each time you want to remove an element.
std::set are orderd and can erase elements by value. the underlying datastructure is a binary search tree, thats why its cheaper to erase elements by value.
a priority queue would have to linearly search through the queue, so its possible but just not very efficient, thats why they didnt include it.