00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef __QUEUE_HH
00019 # define __QUEUE_HH
00020 # include "node.hh"
00021 # include "label.hh"
00022 # include "frame.hh"
00023 # include "../memory/pool_allocator.hh"
00024 # include <unordered_map>
00025
00026 namespace aurelia {
00027 namespace llstack {
00028
00029 struct rj_t {
00030 struct ln: public std::pair<label, node> {
00031 private:
00032 unsigned _hash;
00033 public:
00034 typedef std::pair<label, node> super;
00035 ln(const label& l, const node& n): super(l, n) {
00036 _hash = this->first.hash();
00037 _hash = (_hash << 11) | (_hash >> 21);
00038 _hash ^= this->second.hash();
00039 }
00040 unsigned hash() const {
00041 return _hash;
00042 }
00043
00044 ln(const ln& other): super(other.first, other.second),
00045 _hash(other._hash) {
00046
00047 }
00048
00049 ln& operator=(const ln& other) {
00050 return *this = ln(other);
00051 }
00052
00053 ln& operator=(ln&& other) {
00054 std::swap(this->first, other.first);
00055 std::swap(this->second, other.second);
00056 std::swap(_hash, other._hash);
00057 return *this;
00058 }
00059 };
00060
00061 struct hash {
00062 unsigned operator()(const ln& a) const {
00063 return a.hash();
00064 }
00065 };
00066
00067 struct eq {
00068 unsigned operator()(const ln& a, const ln& b) const {
00069 return ((a.first) == (b.first)) && (a.second == b.second);
00070 }
00071 };
00072
00073 typedef std::unordered_set<frame, frame::hash_op, frame::eq, pool_allocator<frame> > frame_set_t;
00074 typedef std::unordered_map<ln, frame_set_t, hash, eq, pool_allocator<std::pair<ln, frame_set_t> > > set_t;
00075 set_t done;
00076 set_t pending;
00077 };
00078
00079 struct descriptor {
00080 label L;
00081 frame f;
00082 node n;
00083 stream s;
00084
00085 descriptor(const label& L, const frame& f, const node& n, const stream& s):
00086 L(L), f(f), n(n), s(s) {}
00087 descriptor(const descriptor& other): L(other.L),
00088 f(other.f), n(other.n), s(other.s) {
00089 }
00090 };
00091
00092 struct r_t {
00093 struct eof {};
00094 typedef std::map<stream, rj_t, std::less<stream>, pool_allocator<std::pair<stream, rj_t> > > map_t;
00095 map_t m;
00096
00097 descriptor pop() {
00098 map_t::iterator i = m.begin();
00099 if (i == m.end()) {
00100 throw eof();
00101 }
00102 while ((*i).second.pending.empty()) {
00103 stream s = (*i).first;
00104 m.erase(i);
00105 node::drop(s);
00106
00107 i = m.begin();
00108 if (i == m.end())
00109 throw eof();
00110 }
00111 rj_t::set_t::iterator j = (*i).second.pending.begin();
00112 rj_t::frame_set_t::iterator f = (*j).second.begin();
00113 frame fr = *f;
00114 rj_t::ln p = (*j).first;
00115 (*i).second.done[(*j).first].insert(*f);
00116 (*j).second.erase(*f);
00117 if ((*j).second.empty()) {
00118 (*i).second.pending.erase(j);
00119 }
00120 return descriptor(p.first, fr, p.second, (*i).first);
00121 }
00122
00123 void collect_nodes() const {
00124 std::unordered_set<node, std::hash<node>, std::equal_to<node>, pool_allocator<node> > marks;
00125 for (map_t::const_iterator i = m.begin();
00126 i != m.end(); ++i) {
00127 for (rj_t::set_t::const_iterator j = (*i).second.pending.begin();
00128 j != (*i).second.pending.end(); ++j) {
00129 (*j).first.second.mark(marks);
00130 }
00131 for (rj_t::set_t::const_iterator j = (*i).second.done.begin();
00132 j != (*i).second.done.end(); ++j) {
00133 (*j).first.second.mark(marks);
00134 }
00135 }
00136 node::clear(marks);
00137 }
00138
00139 void add(const label& L, const frame& data, const node& u, const stream& j) {
00140 rj_t::ln p(L, u);
00141 if (m[j].done[p].find(data) == m[j].done[p].end()) {
00142 m[j].pending[p].insert(data);
00143 }
00144 }
00145 };
00146
00147 }
00148 }
00149
00150 #endif