Pārlūkot izejas kodu

Improve observation mecanism

Eric Ramat 6 gadi atpakaļ
vecāks
revīzija
d907020569

+ 24 - 14
src/paradevs/common/Coordinator.hpp

@@ -60,33 +60,43 @@ public :
         const GraphManager < Time >& graph_manager =
             get_graph_manager();
         typename common::ModelMap < Time >::const_iterator it =
-            graph_manager.children().find(index);
+            graph_manager.child_map().find(index);
 
-        if (it != graph_manager.children().end()) {
+        if (it != graph_manager.child_map().end()) {
             return it->second;
         } else {
             return nullptr;
         }
     }
 
-    virtual const Model < Time >* get_submodel(unsigned int /* index */,
-                                               unsigned int /* rank */) const
+    virtual const Model < Time >* get_submodel(unsigned int index,
+                                               unsigned int rank) const
     {
-/*        const GraphManager < Time >& graph_manager =
+        const GraphManager < Time >& graph_manager =
             get_graph_manager();
-        typename common::Models < Time >::const_iterator it =
-            graph_manager.children().find(index);
-
-
-        typename AbstractCoupledModel::Setsubmodels::const_iterator it =
-            setsubmodels.find(index);
+        typename common::ModelsMap < Time >::const_iterator it =
+            graph_manager.children_map().find(index);
 
-        if (it != setsubmodels.end() and it->second.size() > rank) {
+        if (it != graph_manager.children_map().end() and
+            it->second.size() > rank) {
             return it->second.at(rank);
         } else {
             return nullptr;
-            } */
-        return nullptr;
+        }
+    }
+
+    virtual unsigned int get_submodel_number(unsigned int index) const
+    {
+        const GraphManager < Time >& graph_manager =
+            get_graph_manager();
+        typename common::ModelsMap < Time >::const_iterator it =
+            graph_manager.children_map().find(index);
+
+        if (it != graph_manager.children_map().end()) {
+            return it->second.size();
+        } else {
+            return 0;
+        }
     }
 
     virtual bool is_atomic() const

+ 24 - 5
src/paradevs/common/GraphManager.hpp

@@ -50,19 +50,38 @@ public:
 
     void add_child(unsigned int index, common::Model < Time >* child)
     {
-        _child_list[index] = child;
+        _children.push_back(child);
+        _child_map[index] = child;
         child->set_parent(_coordinator);
     }
 
-    const common::ModelMap < Time >& children() const
-    { return _child_list; }
+    void add_children(unsigned int index, common::Model < Time >* child)
+    {
+        _children.push_back(child);
+        if (_children_map.find(index) == _children_map.end()) {
+            _children_map[index] = Models < Time >();
+        }
+        _children_map[index].push_back(child);
+        child->set_parent(_coordinator);
+    }
+
+    const common::Models < Time >& children() const
+    { return _children; }
+
+    const common::ModelMap < Time >& child_map() const
+    { return _child_map; }
+
+    const common::ModelsMap < Time >& children_map() const
+    { return _children_map; }
 
     common::Coordinator < Time >* get_coordinator() const
     { return _coordinator; }
 
 protected:
-    common::ModelMap < Time >     _child_list;
-    common::Coordinator < Time >* _coordinator;
+    common::Models < Time >        _children;
+    common::ModelMap < Time >      _child_map;
+    common::ModelsMap < Time >     _children_map;
+    common::Coordinator < Time >*  _coordinator;
 };
 
 } } // namespace paradevs common

+ 30 - 0
src/paradevs/common/Model.hpp

@@ -128,11 +128,17 @@ public:
                                                unsigned int rank) const
     { (void)index; (void)rank; assert(false); }
 
+    virtual unsigned int get_submodel_number(unsigned int index) const
+    { (void)index; assert(false); }
+
     virtual bool is_atomic() const = 0;
 
     virtual bool is_remote() const
     { return false; }
 
+    std::string path() const
+    { return (_parent != nullptr ? _parent->path() : "") + ":" + get_name(); }
+
     void set_parent(Model < Time >* parent)
     { _parent = parent; }
 
@@ -257,6 +263,30 @@ public:
     }
 };
 
+template < class Time >
+class ModelsMap : public std::map < unsigned int, Models < Time > >
+{
+public:
+    ModelsMap()
+    { }
+    virtual ~ModelsMap()
+    { }
+
+    std::string to_string() const
+    {
+        std::ostringstream ss;
+
+        ss << "{ ";
+        for (typename ModelsMap < Time >::const_iterator it =
+                 ModelsMap < Time >::begin();
+             it != ModelsMap < Time >::end(); ++it) {
+            ss << it->second.to_string() << " ";
+        }
+        ss << "}";
+        return ss.str();
+    }
+};
+
 } } // namespace paradevs common
 
 #endif

+ 97 - 49
src/paradevs/common/observer/View.hpp

@@ -31,6 +31,7 @@
 #include <paradevs/common/time/DoubleTime.hpp>
 #include <paradevs/common/Value.hpp>
 
+#include <boost/format.hpp>
 #include <boost/lexical_cast.hpp>
 
 namespace paradevs { namespace observer {
@@ -38,11 +39,14 @@ namespace paradevs { namespace observer {
 template < typename Time >
 class View
 {
-    typedef std::vector < unsigned int > Selector;
+    typedef std::vector < int > Selector;
 
 public:
-    typedef std::vector < std::pair < double, common::Value > > Value;
-    typedef std::map < std::string, Value > Values;
+    typedef std::vector < std::pair < double, common::Value > > Values;
+    typedef std::map < std::string, Values > VariableValues;
+    typedef std::map < std::string, VariableValues > SelectorValues;
+
+    enum vars { ALL = -1 };
 
     View() : _model(0)
     { }
@@ -57,12 +61,12 @@ public:
     {
         double t = common::DoubleTime::infinity;
 
-        for (Values::const_iterator it = _values.begin(); it!= _values.end();
-             ++it) {
-            if (t > it->second.begin()->first) {
-                t = it->second.begin()->first;
-            }
-        }
+        // for (SelectorValues::const_iterator it = _values.begin(); it!= _values.end();
+        //      ++it) {
+        //     if (t > it->second.begin()->first) {
+        //         t = it->second.begin()->first;
+        //     }
+        // }
         return t;
     }
 
@@ -70,19 +74,19 @@ public:
     {
         View* v = new View();
 
-        v->_selectors = _selectors;
-        for (Values::const_iterator it = _values.begin(); it!= _values.end();
-             ++it) {
+        // v->_selectors = _selectors;
+        // for (Values::const_iterator it = _values.begin(); it!= _values.end();
+        //      ++it) {
 
-            v->_values[it->first] = Value();
-            Value::const_iterator itp = it->second.begin();
+        //     v->_values[it->first] = Value();
+        //     Value::const_iterator itp = it->second.begin();
 
-            while (itp != it->second.end()) {
-                v->_values[it->first].push_back(*itp);
-                ++itp;
-            }
-        }
-        v->_model = 0;
+        //     while (itp != it->second.end()) {
+        //         v->_values[it->first].push_back(*itp);
+        //         ++itp;
+        //     }
+        // }
+        // v->_model = 0;
         return v;
     }
 
@@ -90,28 +94,35 @@ public:
     {
         double t = 0;
 
-        for (Values::const_iterator it = _values.begin(); it!= _values.end();
-             ++it) {
-            if (t < it->second.back().first) {
-                t = it->second.back().first;
-            }
-        }
+        // for (SelectorValues::const_iterator it = _values.begin(); it!= _values.end();
+        //      ++it) {
+        //     if (t < it->second.back().first) {
+        //         t = it->second.back().first;
+        //     }
+        // }
         return t;
     }
 
-    double get(double t, const std::string& name) const
+    double get(double t, const std::string& selector_name,
+               const std::string& variable_name) const
     {
-        Values::const_iterator it = _values.find(name);
+        SelectorValues::const_iterator it = _values.find(selector_name);
 
         if (it != _values.end()) {
-            Value::const_iterator itp = it->second.begin();
+            VariableValues::const_iterator itp = it->second.find(variable_name);
 
-            while (itp != it->second.end() and itp->first < t) {
-                ++itp;
-            }
             if (itp != it->second.end()) {
-                // TODO: to improve
-                return boost::lexical_cast < double >(itp->second);
+                Values::const_iterator itv = itp->second.begin();
+
+                while (itv != itp->second.end() and itv->first < t) {
+                    ++itv;
+                }
+                if (itv != itp->second.end()) {
+                    // TODO: to improve
+                    return boost::lexical_cast < double >(itv->second);
+                } else {
+                    return 0;
+                }
             } else {
                 return 0;
             }
@@ -119,17 +130,59 @@ public:
         return 0;
     }
 
-    const Value& get(const std::string& name) const
+    const Values& get(const std::string& selector_name, const std::string& variable_name) const
     {
-        Values::const_iterator it = _values.find(name);
+        SelectorValues::const_iterator it = _values.find(selector_name);
 
         if (it != _values.end()) {
-            return it->second;
+            VariableValues::const_iterator itv = it->second.find(variable_name);
+
+            if (itv != it->second.end()) {
+                return itv->second;
+            } else {
+                assert(false);
+            }
         } else {
             assert(false);
         }
     }
 
+    void observe(double time, const common::Model < common::DoubleTime >* model,
+                 const std::string& selector_name, unsigned int variable_index)
+    {
+        std::string path = (boost::format("%1%:%2%") % model->path() % variable_index).str() ;
+        VariableValues& values = _values[selector_name];
+
+        if (values.find(path) == values.end()) {
+            values[path] = Values();
+        }
+        values[path].push_back(
+            std::make_pair(time, model->observe(time, variable_index)));
+    }
+
+    void observe(const Selector& chain, unsigned int i,
+                 double time, const common::Model < common::DoubleTime >* model,
+                 const std::string& selector_name, unsigned int variable_index)
+    {
+        while (i < chain.size() - 1 and chain[i + 1] != ALL and model) {
+            assert(chain[i] >= 0);
+            model = model->get_submodel((unsigned int)chain[i]);
+            ++i;
+        }
+        if (chain[i + 1] == ALL) {
+            for (size_t model_index = 0; model_index < model->get_submodel_number(chain[i]);
+                 ++model_index) {
+                assert(chain[i] >= 0);
+                observe(chain, i + 2, time, model->get_submodel((unsigned int)chain[i], model_index),
+                        selector_name, variable_index);
+            }
+        } else {
+            if (model) {
+                observe(time, model, selector_name, variable_index);
+            }
+        }
+    }
+
     virtual void observe(double time)
     {
         for (typename Selectors::const_iterator it = _selectors.begin();
@@ -139,34 +192,29 @@ public:
             if (it->second.size() > 1) {
                 size_t i = 0;
 
-                while (i < it->second.size() - 1 and model) {
-                    model = model->get_submodel(it->second[i]);
-                    ++i;
+                observe(it->second, i, time, model, it->first, it->second.back());
+            } else {
+                if (model) {
+                    observe(time, model, it->first, it->second.back());
                 }
             }
-            if (model) {
-                _values[it->first].push_back(
-                    std::make_pair(time,
-                                   model->observe(time,
-                                                  it->second.back())));
-            }
         }
     }
 
     void selector(const std::string& name, const Selector& chain)
     {
         _selectors[name] = chain;
-        _values[name] = Value();
+        _values[name] = VariableValues();
     }
 
-    const Values& values() const
+    const SelectorValues& values() const
     { return _values;}
 
 private:
     typedef std::map < std::string, Selector > Selectors;
 
     Selectors                               _selectors;
-    Values                                  _values;
+    SelectorValues                          _values;
     const paradevs::common::Model < Time >* _model;
 };
 

+ 6 - 6
src/paradevs/kernel/pdevs/Coordinator.hpp

@@ -90,7 +90,7 @@ public:
         assert(_graph_manager.children().size() > 0);
 
         for (auto & child : _graph_manager.children()) {
-            _event_table.init(child.second->start(t), child.second);
+            _event_table.init(child->start(t), child);
         }
         type::_tl = t;
         type::_tn = _event_table.get_current_time();
@@ -287,10 +287,10 @@ public:
         common::Models < Time >& receivers)
     {
         for (auto & model : _graph_manager.children()) {
-            if (model.second->event_number() > 0) {
+            if (model->event_number() > 0) {
                 if (std::find(receivers.begin(), receivers.end(),
-                              model.second) == receivers.end()) {
-                    receivers.push_back(model.second);
+                              model) == receivers.end()) {
+                    receivers.push_back(model);
                 }
             }
         }
@@ -299,8 +299,8 @@ public:
     void update_event_table(typename Time::type t)
     {
         for (auto & model : _graph_manager.children()) {
-            if (model.second->event_number() > 0) {
-                _event_table.put(t, model.second);
+            if (model->event_number() > 0) {
+                _event_table.put(t, model);
             }
         }
     }

+ 2 - 2
src/paradevs/kernel/pdevs/GraphManager.hpp

@@ -140,8 +140,8 @@ public:
     	std::ostringstream ss;
 
     	ss << common::spaces(level * 2) << "Childs :" << std::endl;
-        for (auto & child : common::GraphManager < Time >::_child_list) {
-            ss << child.second->to_string(level + 1);
+        for (auto & child : common::GraphManager < Time >::_children) {
+            ss << child->to_string(level + 1);
         }
         ss << _link_list.to_string(level);
         return ss.str();