00001
00002
00003
00004
00005
00006
00007
00008 #ifndef EDG_WORKLOAD_COMMON_REQUESTAD_DAGAD_H
00009 #define EDG_WORKLOAD_COMMON_REQUESTAD_DAGAD_H
00010
00011 #include <string>
00012 #include <utility>
00013 #include <map>
00014 #include <set>
00015 #include <iosfwd>
00016 #include <classad_distribution.h>
00017
00018 namespace edg {
00019 namespace workload {
00020 namespace common {
00021 namespace requestad {
00022
00023 struct InvalidDAGInfo {};
00024 struct InvalidNodeInfo {};
00025
00026 class DAGAdNodeIterator
00027 : public std::iterator<
00028 std::input_iterator_tag
00029 ,std::pair<std::string, classad::ExprTree const*>
00030 ,std::iterator_traits<classad::ClassAd::const_iterator>::difference_type
00031 ,std::pair<std::string, classad::ExprTree const*> const*
00032 ,std::pair<std::string, classad::ExprTree const*> const&
00033 >
00034 {
00035 friend bool operator==(DAGAdNodeIterator const& lhs, DAGAdNodeIterator const& rhs);
00036
00037 classad::ClassAd const* m_nodes;
00038 classad::ClassAd::const_iterator m_node;
00039 value_type m_value;
00040
00041 bool is_good() const
00042 {
00043 return m_node != m_nodes->end();
00044 }
00045
00046 void set_value()
00047 {
00048 if (is_good()) {
00049 m_value = *m_node;
00050 }
00051 }
00052
00053 public:
00054
00055 DAGAdNodeIterator()
00056 : m_nodes(0), m_node(), m_value()
00057 {
00058 }
00059
00060 DAGAdNodeIterator(classad::ClassAd const* nodes, classad::ClassAd::const_iterator it)
00061 : m_nodes(nodes), m_node(it), m_value()
00062 {
00063 if (m_node != nodes->end()
00064 && m_node->second->GetKind() != classad::ExprTree::CLASSAD_NODE) {
00065 operator++();
00066 }
00067 set_value();
00068 }
00069
00070 DAGAdNodeIterator& operator++()
00071 {
00072 if (m_node != m_nodes->end()) {
00073 do {
00074 ++m_node;
00075 } while (m_node != m_nodes->end()
00076 && m_node->second->GetKind() != classad::ExprTree::CLASSAD_NODE);
00077 }
00078
00079 set_value();
00080
00081 return *this;
00082 }
00083
00084 DAGAdNodeIterator operator++(int)
00085 {
00086 DAGAdNodeIterator tmp(*this);
00087 ++*this;
00088 return tmp;
00089 }
00090
00091 reference operator*() const
00092 {
00093 return m_value;
00094 }
00095
00096 pointer operator->() const
00097 {
00098 return &(operator*());
00099 }
00100
00101 };
00102
00103 inline bool operator==(DAGAdNodeIterator const& lhs, DAGAdNodeIterator const& rhs)
00104 {
00105 return lhs.m_nodes == rhs.m_nodes && lhs.m_node == rhs.m_node;
00106 }
00107
00108 inline bool operator!=(DAGAdNodeIterator const& lhs, DAGAdNodeIterator const& rhs)
00109 {
00110 return !(lhs == rhs);
00111 }
00112
00113 struct DAGAdDependencyIterator
00114 : public std::iterator<
00115 std::input_iterator_tag
00116 ,std::pair<DAGAdNodeIterator, DAGAdNodeIterator>
00117 ,ptrdiff_t
00118 ,std::pair<DAGAdNodeIterator, DAGAdNodeIterator> const*
00119 ,std::pair<DAGAdNodeIterator, DAGAdNodeIterator> const&
00120 >
00121 {
00122 friend bool operator==(DAGAdDependencyIterator const& lhs,
00123 DAGAdDependencyIterator const& rhs);
00124
00125 typedef DAGAdNodeIterator node_iterator;
00126 typedef classad::ExprList::iterator Iterator;
00127
00128 classad::ClassAd const* m_nodes;
00129 Iterator m_dep;
00130 Iterator m_dep_end;
00131 Iterator m_parent;
00132 Iterator m_child;
00133 value_type m_value;
00134
00135 static classad::ExprList* parents(classad::ExprTree* dep)
00136 {
00137 return dynamic_cast<classad::ExprList*>(*dynamic_cast<classad::ExprList*>(dep)->begin());
00138 }
00139 static classad::ExprList* children(classad::ExprTree* dep)
00140 {
00141 return dynamic_cast<classad::ExprList*>(*++dynamic_cast<classad::ExprList*>(dep)->begin());
00142 }
00143 bool is_good() const { return m_dep != m_dep_end; }
00144 void set_value()
00145 {
00146 if (is_good()) {
00147 using namespace classad;
00148
00149 ExprTree* t;
00150 std::string node1;
00151 std::string node2;
00152 bool a;
00153 dynamic_cast<AttributeReference const*>(*m_parent)->GetComponents(t, node1, a);
00154 dynamic_cast<AttributeReference const*>(*m_child)->GetComponents(t, node2, a);
00155 m_value = std::make_pair(
00156 node_iterator(m_nodes, m_nodes->find(node1)),
00157 node_iterator(m_nodes, m_nodes->find(node2))
00158 );
00159 }
00160 }
00161
00162 DAGAdDependencyIterator(classad::ClassAd const* nodes = 0, bool begin = false)
00163 : m_nodes(nodes), m_dep(), m_dep_end(), m_parent(), m_child()
00164 {
00165 if (nodes) {
00166 using namespace classad;
00167 ExprList* deps = dynamic_cast<ExprList*>(nodes->Lookup("dependencies"));
00168
00169 if (begin) {
00170 m_dep = deps->begin();
00171 m_dep_end = deps->end();
00172 m_parent = parents(*m_dep)->begin();
00173 m_child = children(*m_dep)->begin();
00174 set_value();
00175 } else {
00176 m_dep = deps->end();
00177 m_dep_end = deps->end();
00178 }
00179 }
00180 }
00181
00182
00183
00184 DAGAdDependencyIterator& operator++()
00185 {
00186 ++m_child;
00187 if (m_child == children(*m_dep)->end()) {
00188 ++m_parent;
00189 if (m_parent == parents(*m_dep)->end()) {
00190 ++m_dep;
00191 if (m_dep != m_dep_end) {
00192 m_parent = parents(*m_dep)->begin();
00193 m_child = children(*m_dep)->begin();
00194 }
00195 } else {
00196 m_child = children(*m_dep)->begin();
00197 }
00198 }
00199
00200 set_value();
00201
00202 return *this;
00203 }
00204
00205 DAGAdDependencyIterator operator++(int)
00206 {
00207 DAGAdDependencyIterator tmp(*this);
00208 ++*this;
00209 return tmp;
00210 }
00211
00212 reference operator*() const
00213 {
00214 return m_value;
00215 }
00216
00217 pointer operator->() const
00218 {
00219 return &(operator*());
00220 }
00221 };
00222
00223 inline bool operator==(DAGAdDependencyIterator const& lhs,
00224 DAGAdDependencyIterator const& rhs)
00225 {
00226 return (!lhs.is_good() && !rhs.is_good())
00227 || (lhs.is_good() && rhs.is_good()
00228 && lhs.m_dep == rhs.m_dep
00229 && lhs.m_parent == rhs.m_parent
00230 && lhs.m_child == rhs.m_child
00231 );
00232 }
00233
00234 inline bool operator!=(DAGAdDependencyIterator const& lhs,
00235 DAGAdDependencyIterator const& rhs)
00236 {
00237 return !(lhs == rhs);
00238 }
00239
00240 class DAGAd
00241 {
00242 public:
00243
00244 typedef DAGAdNodeIterator node_iterator;
00245 typedef DAGAdNodeIterator::value_type node_value_type;
00246 typedef DAGAdDependencyIterator dependency_iterator;
00247 typedef DAGAdDependencyIterator::value_type dependency_value_type;
00248
00249 private:
00250 classad::ClassAd m_ad;
00251
00252 public:
00253 DAGAd();
00254 explicit DAGAd(classad::ClassAd const& ad);
00255
00256 classad::ClassAd const& ad() const;
00257
00258 int max_nodes_running(int n);
00259 int max_nodes_running() const;
00260 std::string default_node_type(std::string const& type);
00261 std::string default_node_type() const;
00262 bool add_node(std::string const& name, classad::ClassAd const& info);
00263 bool remove_node(std::string const& name);
00264 bool add_dependency(std::string const& first, std::string const& second);
00265 bool remove_dependency(std::string const& first, std::string const& second);
00266
00267 std::pair<dependency_iterator, dependency_iterator> dependencies() const;
00268 std::pair<node_iterator, node_iterator> nodes() const;
00269 };
00270
00271 }}}}
00272
00273 #endif