Line data Source code
1 :
2 : /* Copyright (c) 2011-2013, Stefan Eilemann <eile@eyescale.ch>
3 : *
4 : * This file is part of Collage <https://github.com/Eyescale/Collage>
5 : *
6 : * This library is free software; you can redistribute it and/or modify it under
7 : * the terms of the GNU Lesser General Public License version 2.1 as published
8 : * by the Free Software Foundation.
9 : *
10 : * This library is distributed in the hope that it will be useful, but WITHOUT
11 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13 : * details.
14 : *
15 : * You should have received a copy of the GNU Lesser General Public License
16 : * along with this library; if not, write to the Free Software Foundation, Inc.,
17 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 : */
19 :
20 : #ifndef CO_CONNECTIONS_H
21 : #define CO_CONNECTIONS_H
22 :
23 : #include <co/connection.h>
24 : #include <co/node.h>
25 : #include <co/types.h>
26 : #include <lunchbox/hash.h>
27 :
28 : #include <set>
29 :
30 : namespace co
31 : {
32 : /** @internal
33 : * Collect all connections of a set of nodes.
34 : *
35 : * Gives priority to multicast connections if a multicast connection is used
36 : * more than once. Connections are added to the result vector. Multicast
37 : * connections are added at most once. The result vector should be empty on
38 : * entry. The order of connections may not match the order of nodes.
39 : *
40 : * @param nodes the nodes to send to.
41 : * @param result the connection vector receiving new connections.
42 : */
43 239 : inline Connections gatherConnections( const Nodes& nodes )
44 : {
45 239 : Connections result;
46 : typedef stde::hash_map< ConstConnectionDescriptionPtr, NodePtr,
47 : lunchbox::hashRefPtr< const ConnectionDescription > >
48 : MCNodes;
49 478 : MCNodes mcNodes; // first node using a multicast connection
50 :
51 : typedef std::set< ConstConnectionDescriptionPtr > MCSet;
52 478 : MCSet mcSet; // multicast connection is added
53 :
54 359 : for( Nodes::const_iterator i = nodes.begin(); i != nodes.end(); ++i )
55 : {
56 120 : NodePtr node = *i;
57 240 : ConnectionPtr connection = node->getConnection( true /* preferMC */);
58 120 : LBASSERT( connection );
59 120 : if( !connection )
60 0 : continue;
61 :
62 120 : if( connection->isMulticast( ))
63 : {
64 0 : ConstConnectionDescriptionPtr desc = connection->getDescription();
65 0 : if( mcSet.find( desc ) != mcSet.end( )) // already added
66 0 : continue;
67 :
68 0 : MCNodes::iterator j = mcNodes.find( desc );
69 0 : if( j == mcNodes.end( ))
70 : {
71 : // first appearance of multicast connection
72 0 : mcNodes[ desc ] = node;
73 0 : continue;
74 : }
75 :
76 0 : mcSet.insert( desc ); // mark as added
77 0 : mcNodes.erase( j );
78 : }
79 :
80 120 : result.push_back( connection );
81 120 : }
82 :
83 : // Add unicast connections for multicast node connections seen only once
84 239 : for( MCNodes::iterator i = mcNodes.begin(); i != mcNodes.end(); ++i )
85 : {
86 0 : ConnectionPtr connection = i->second->getConnection();
87 0 : LBASSERT( connection.isValid( ));
88 :
89 0 : if( connection.isValid( ))
90 0 : result.push_back( connection );
91 0 : }
92 478 : return result;
93 : }
94 :
95 : }
96 :
97 : #endif //CO_CONNECTIONS_H
|