Menu

NodeRepository.h

Go to the documentation of this file.
00001 /*******************************************************************************
00002  *
00003  * Copyright (c) 2008-2010 Michael Schulze <mschulze@ivs.cs.uni-magdeburg.de>
00004  *               2009-2010 Michael Kriese <kriese@cs.uni-magdeburg.de>
00005  * All rights reserved.
00006  *
00007  *    Redistribution and use in source and binary forms, with or without
00008  *    modification, are permitted provided that the following conditions
00009  *    are met:
00010  *
00011  *    * Redistributions of source code must retain the above copyright
00012  *      notice, this list of conditions and the following disclaimer.
00013  *
00014  *    * Redistributions in binary form must reproduce the above copyright
00015  *      notice, this list of conditions and the following disclaimer in
00016  *      the documentation and/or other materials provided with the
00017  *      distribution.
00018  *
00019  *    * Neither the name of the copyright holders nor the names of
00020  *      contributors may be used to endorse or promote products derived
00021  *      from this software without specific prior written permission.
00022  *
00023  *
00024  *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
00025  *    IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
00026  *    TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00027  *    PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00028  *    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00029  *    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00030  *    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00031  *    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00032  *    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00033  *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00034  *    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00035  *
00036  *
00037  * $Id$
00038  *
00039  ******************************************************************************/
00040 #ifndef __NodeRepository_hpp__
00041 #define __NodeRepository_hpp__
00042 
00043 #include <map>
00044 #include <list>
00045 #include <ctime>
00046 #include "boost/noncopyable.hpp"
00047 #include "boost/shared_ptr.hpp"
00048 #include "boost/shared_container_iterator.hpp"
00049 #include <boost/mpl/for_each.hpp>
00050 #include "mw/common/Subject.h"
00051 #include "mw/nl/awds/MAC.h"
00052 #include "mw/nl/awds/Node.h"
00053 #include "mw/nl/awds/Attributes.h"
00054 #include "mw/nl/awds/ComparableAttributeSet.h"
00055 
00056 namespace famouso {
00057     namespace mw {
00058         namespace nl {
00059             namespace awds {
00060 
00062                 typedef ComparableAttributeSet<AWDSAttributeSet::type> Attributes;
00063 
00065                 typedef detail::Node<AWDSAttributeSet::type> Node;
00066 
00072                 class NodeRepository: boost::noncopyable {
00073 
00074                     public:
00075 
00077                         typedef NodeRepository type;
00078 
00079                         typedef boost::shared_container_iterator<std::list<Node::type> > NodeIterator;
00080 
00083                         typedef famouso::mw::Subject SNN;
00084 
00085                     private:
00086 
00089                         class Subscriber: boost::noncopyable {
00090 
00091                                 clock_t _time; 
00093                                 Subscriber() :
00094                                     _time(std::clock()) {
00095                                 }
00096 
00097                             public:
00098 
00101                                 typedef boost::shared_ptr<Subscriber> type;
00102 
00110                                 static type Create(Attributes::type a, FlowId fId = 0) {
00111                                     type res = type(new Subscriber());
00112                                     res->attribs = a;
00113                                     res->flowId = fId;
00114                                     return res;
00115                                 }
00116 
00121                                 int elapsed() const {
00122                                     return static_cast<int> (std::clock() - _time);
00123                                 }
00124 
00125                                 Attributes::type attribs; 
00126                                 FlowId flowId; 
00127                         };
00128 
00135                         template< class AttrSet >
00136                         class attr_finder {
00138                                 typedef typename AttrSet::sequence Seq;
00139 
00140                                 AttrSet &_res; 
00141                                 Attributes::type &_pub, 
00142                                 &_sub; 
00150                                 attr_finder(AttrSet &res, Attributes::type &pub, Attributes::type &sub) :
00151                                     _res(res), _pub(pub), _sub(sub) {
00152                                 }
00153 
00154                             public:
00155 
00162                                 static void apply(AttrSet &res, Attributes::type &pub, Attributes::type &sub) {
00163                                     boost::mpl::for_each<Seq>(attr_finder(res, pub, sub));
00164                                 }
00165 
00170                                 template< class Attrib >
00171                                 void operator()(Attrib a) {
00173                                     typedef typename Attrib::comparator cmp;
00174 
00175                                     if (!Attrib::highDensity)
00176                                         return; // Only high density attributes are searched.
00177 
00178                                     // The resulting attribute
00179                                     Attrib *r = _res.template find_rt<Attrib> ();
00180                                     // the publisher attribute
00181                                     Attrib *p = _pub->template find<Attrib> ();
00182                                     // the subscriber attribute
00183                                     Attrib *s = _sub->template find<Attrib> ();
00184 
00185                                     if (p) {
00186                                         // publisher attibute is defined
00187                                         if (s && cmp::apply_runtime(p->getValue(), s->getValue()))
00188                                             // subscriber attribute is also defined and stricter, so use this
00189                                             r->setValue(s->getValue());
00190                                         else
00191                                             // subscriber attribute not defined or not stricter, so use publisher attribute
00192                                             r->setValue(p->getValue());
00193                                     } else if (s) {
00194                                         // only subscriber attibute is defined
00195                                         r->setValue(s->getValue());
00196                                     } else
00197                                         log::emit<AWDS>() << "Missing attribute with id " << (int) Attrib::id << log::endl;
00198                                 }
00199                         };
00200 
00202                         typedef std::list<Node::type> NodeList;
00203 
00206                         typedef std::map<Node::type, Subscriber::type, Node::comp> NodeSubscriberMap;
00207 
00210                         typedef std::map<SNN, boost::shared_ptr<NodeSubscriberMap> > SubscriberMap;
00211 
00214                         typedef std::map<SNN, Attributes::type> PublisherMap;
00215 
00218                         //typedef std::list<Node::type, Node::comp> NodeList;
00219 
00221                         NodeRepository();
00222 
00223                         Subscriber::type findSub(Node::type &node, SNN subject);
00224 
00225                     public:
00226 
00231                         static type& getInstance();
00232 
00239                         Node::type find(MAC &mac);
00240 
00249                         std::pair<NodeIterator, NodeIterator> find(SNN subject);
00250 
00257                         FlowId flowid(Node::type &node, SNN subject);
00258 
00265                         int elapsed(Node::type &node, SNN subject);
00266 
00275                         template< class AttrSet >
00276                         void find(Node::type &node, SNN subject, AttrSet &cas) {
00277                             Attributes::type subAttr, pubAttr = _snnAttribs[subject];
00278 
00279                             // find the subsciber
00280                             Subscriber::type s = findSub(node, subject);
00281                             if (s) // we found the subscriber
00282                                 subAttr = s->attribs; // get the subscriber attributes
00283 
00284                             if (pubAttr && subAttr)
00285                                 attr_finder<AttrSet>::apply(cas, pubAttr, subAttr);
00286                             else
00287                                 log::emit<AWDS>() << "Missing attributes of subscriber or publisher." << log::endl;
00288                         }
00289 
00295                         void remove(Node::type &node);
00296 
00303                         void remove(SNN &subject);
00304 
00313                         void reg(Node::type &node, SNN &subject, Attributes::type &attribs);
00314 
00320                         void reg(SNN subject, Attributes::type &attribs);
00321 
00326                         void unreg(Node::type &node);
00327 
00333                         void unreg(Node::type &node, SNN subject);
00334 
00341                         void update(Node::type &node, SNN subject, FlowId fId);
00342 
00343                     private:
00344                         SubscriberMap _snnmap; 
00345                         NodeList _nodes; 
00346                         PublisherMap _snnAttribs; 
00347                 };
00348 
00349             } /* namespace awds */
00350         } /* namespace nl */
00351     } /* namespace mw */
00352 } /* namespace famouso */
00353 #endif /* __ClientRepository_hpp__ */