20 #ifndef GALOIS_GSLIST_H
21 #define GALOIS_GSLIST_H
23 #include <type_traits>
25 #include <boost/iterator/iterator_facade.hpp>
26 #include <boost/mpl/if.hpp>
28 #include "galois/config.h"
34 template <
typename T,
int ChunkSize,
bool Concurrent>
42 typedef typename boost::mpl::if_c<Concurrent,
46 struct Block :
public Ring {
53 :
public boost::iterator_facade<outer_iterator<U>, U,
54 boost::forward_traversal_tag> {
55 friend class boost::iterator_core_access;
58 void increment() { cur = cur->next; }
60 template <
typename OtherTy>
61 bool equal(
const outer_iterator<OtherTy>& o)
const {
65 U& dereference()
const {
return *cur; }
68 outer_iterator(U* c = 0) : cur(c) {}
70 template <
typename OtherTy>
71 outer_iterator(
const outer_iterator<OtherTy>& o) : cur(o.cur) {}
75 typename boost::mpl::if_c<Concurrent, std::atomic<Block*>, Block*>::type
80 template <
typename HeapTy>
81 Block* alloc_block(HeapTy& heap) {
82 return new (heap.allocate(
sizeof(Block))) Block();
85 template <
typename HeapTy>
86 void free_block(HeapTy& heap, Block* b) {
91 void free_block(promise_to_dealloc, Block* b) { b->~Block(); }
93 template <
typename HeapTy,
bool C = Concurrent>
94 auto extend_first(HeapTy& heap) ->
typename std::enable_if<C>::type {
95 Block* b = alloc_block(heap);
97 Block* f = first.load(std::memory_order_relaxed);
99 if (first.compare_exchange_weak(f, b))
104 template <
typename HeapTy,
bool C = Concurrent>
105 auto extend_first(HeapTy& heap) ->
typename std::enable_if<!C>::type {
106 Block* b = alloc_block(heap);
116 const Block* get_first()
const {
121 template <
typename U,
bool C = Concurrent>
122 auto shrink_first(Block* old_first, U&& arg) ->
123 typename std::enable_if<C>::type {
124 if (first.compare_exchange_strong(old_first, old_first->next)) {
126 free_block(std::forward<U>(arg), old_first);
130 template <
typename U,
bool C = Concurrent>
131 auto shrink_first(Block* old_first, U&& arg) ->
132 typename std::enable_if<!C>::type {
133 if (first != old_first)
135 first = old_first->next;
137 free_block(std::forward<U>(arg), old_first);
140 template <
typename U>
141 void _clear(U&& arg) {
142 Block* b = get_first();
144 shrink_first(b, std::forward<U>(arg));
149 template <
typename U>
150 bool _pop_front(U&& arg) {
152 Block* b = get_first();
158 shrink_first(b, std::forward<U>(arg));
167 typename Block::iterator,
171 typename Block::const_iterator,
183 Block* m_first = first;
184 Block* o_first = o.first;
198 outer_iterator<Block>(
nullptr))
204 outer_iterator<Block>(
nullptr))
210 outer_iterator<const Block>(get_first()),
211 outer_iterator<const Block>(
nullptr))
217 outer_iterator<const Block>(get_first()),
218 outer_iterator<const Block>(
nullptr))
223 return first == NULL || (get_first()->empty() && get_first()->next == NULL);
230 template <
typename HeapTy,
typename... Args,
bool C = Concurrent>
232 typename std::enable_if<!C>::type {
233 if (!first || first->full())
235 first->emplace_front(std::forward<Args>(args)...);
238 template <
typename HeapTy,
bool C = Concurrent>
240 typename std::enable_if<C>::type {
242 Block* b = get_first();
243 if (b && b->push_front(v))
249 template <
typename HeapTy,
typename ValueTy,
bool C = Concurrent>
251 typename std::enable_if<!C>::type {
256 template <
typename HeapTy>
258 return _pop_front(heap);
266 template <
typename HeapTy>
278 template <
typename T,
unsigned chunksize = 16>
285 template <
typename T,
unsigned chunksize = 16>
Alternate implementation of ChooseTwoLevelIterator.
Definition: TwoLevelIteratorA.h:40
iterator begin()
Definition: gslist.h:196
bool empty() const
Definition: gslist.h:222
Helper functor, returns t.end()
Definition: TwoLevelIteratorA.h:383
const_iterator begin() const
Definition: gslist.h:208
Unordered collection of bounded size.
Definition: FixedSizeRing.h:38
auto push_front(HeapTy &heap, const value_type &v) -> typename std::enable_if< C >::type
Definition: gslist.h:239
galois::TwoLevelIteratorA< outer_iterator< Block >, typename Block::iterator, std::forward_iterator_tag, GetBegin, GetEnd > iterator
Definition: gslist.h:169
gslist_base & operator=(const gslist_base &)=delete
gslist_base & operator=(gslist_base &&o)
Definition: gslist.h:182
const_iterator end() const
Definition: gslist.h:215
Tag for methods that depend on user to deallocate memory, although gslist will destroy elements...
Definition: gslist.h:39
auto push_front(HeapTy &heap, ValueTy &&v) -> typename std::enable_if<!C >::type
Definition: gslist.h:250
void clear(HeapTy &heap)
Definition: gslist.h:267
iterator end()
Definition: gslist.h:202
gslist_base(gslist_base &&other)
Definition: gslist.h:180
gslist_base()
Definition: gslist.h:175
std::pair< TwoLevelIteratorA< OuterIter, InnerIter, CategoryOrTraversal, InnerBeginFn, InnerEndFn >, TwoLevelIteratorA< OuterIter, InnerIter, CategoryOrTraversal, InnerBeginFn, InnerEndFn > > make_two_level_iterator(OuterIter outer_begin, OuterIter outer_end)
Definition: TwoLevelIteratorA.h:420
bool pop_front(HeapTy &heap)
Returns true if something was popped.
Definition: gslist.h:257
void clear(promise_to_dealloc)
Definition: gslist.h:271
T value_type
Definition: gslist.h:165
galois::TwoLevelIteratorA< outer_iterator< const Block >, typename Block::const_iterator, std::forward_iterator_tag, GetBegin, GetEnd > const_iterator
Definition: gslist.h:173
auto emplace_front(HeapTy &heap, Args &&...args) -> typename std::enable_if<!C >::type
Definition: gslist.h:231
~gslist_base()
Definition: gslist.h:190
const value_type & front() const
Definition: gslist.h:228
bool pop_front(promise_to_dealloc)
Returns true if something was popped.
Definition: gslist.h:262
Block block_type
External allocator must be able to allocate this type.
Definition: gslist.h:164
value_type & front()
Definition: gslist.h:226
Helper functor, returns t.end()
Definition: TwoLevelIteratorA.h:391