00001 00028 #ifndef GALOIS_GSLIST_H 00029 #define GALOIS_GSLIST_H 00030 00031 #include "Galois/Runtime/mm/Mem.h" 00032 00033 #include "Galois/FixedSizeRing.h" 00034 00035 #include <iterator> 00036 00037 namespace Galois { 00038 00041 template<typename T, int ChunkSize=16> 00042 class gslist { 00043 00044 struct Block: public FixedSizeRing<T,ChunkSize> { 00045 Block* next; 00046 Block(): next() {} 00047 }; 00048 00049 Block* first; 00050 00051 template<typename HeapTy> 00052 Block* alloc_block(HeapTy& heap) { 00053 return new (heap.allocate(sizeof(Block))) Block(); 00054 } 00055 00056 template<typename HeapTy> 00057 void free_block(HeapTy& heap, Block* b) { 00058 b->~Block(); 00059 heap.deallocate(b); 00060 } 00061 00062 template<typename HeapTy> 00063 void extend_first(HeapTy& heap) { 00064 Block* b = alloc_block(heap); 00065 b->next = first; 00066 first = b; 00067 } 00068 00069 template<typename HeapTy> 00070 void shrink_first(HeapTy& heap) { 00071 Block* b = first; 00072 first = b->next; 00073 free_block(heap, b); 00074 } 00075 00076 public: 00078 typedef Block block_type; 00079 typedef T value_type; 00080 00081 gslist(): first() { } 00082 00083 ~gslist() { 00084 assert(empty() && "Memory leak if gslist is not empty before destruction"); 00085 } 00086 00087 class iterator : public std::iterator<std::forward_iterator_tag, T> { 00088 Block* b; 00089 unsigned offset; 00090 00091 void advance() { 00092 if (!b) return; 00093 ++offset; 00094 if (offset == b->size()) { 00095 b = b->next; 00096 offset = 0; 00097 } 00098 } 00099 00100 public: 00101 iterator(Block* _b = 0, unsigned _off = 0): b(_b), offset(_off) {} 00102 00103 bool operator==(const iterator& rhs) const { 00104 return b == rhs.b && offset == rhs.offset; 00105 } 00106 00107 bool operator!=(const iterator& rhs) const { 00108 return b != rhs.b || offset != rhs.offset; 00109 } 00110 00111 T& operator*() const { 00112 return b->getAt(offset); 00113 } 00114 00115 iterator& operator++() { 00116 advance(); 00117 return *this; 00118 } 00119 00120 iterator operator++(int) { 00121 iterator tmp(*this); 00122 advance(); 00123 return tmp; 00124 } 00125 }; 00126 00127 iterator begin() const { 00128 return iterator(first); 00129 } 00130 00131 iterator end() const { 00132 return iterator(); 00133 } 00134 00135 bool empty() const { 00136 return first == NULL; 00137 } 00138 00139 value_type& front() { 00140 return first->front(); 00141 } 00142 00143 template<typename HeapTy> 00144 void push_front(HeapTy& heap, const value_type& v) { 00145 if (first && first->push_front(v)) 00146 return; 00147 extend_first(heap); 00148 first->push_front(v); 00149 } 00150 00151 template<typename HeapTy> 00152 void pop_front(HeapTy& heap) { 00153 first->pop_front(); 00154 if (first->empty()) 00155 shrink_first(heap); 00156 } 00157 00158 template<typename HeapTy> 00159 void clear(HeapTy& heap) { 00160 while (first) { 00161 first->clear(); 00162 shrink_first(heap); 00163 } 00164 } 00165 }; 00166 00167 } 00168 00169 #endif