Line data Source code
1 :
2 : /* Copyright (c) 2011-2017, 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 :
27 : #include <lunchbox/hash.h>
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 236 : inline Connections gatherConnections(const Nodes& nodes)
44 : {
45 236 : Connections result;
46 : typedef std::unordered_map<
47 : ConstConnectionDescriptionPtr, NodePtr,
48 : lunchbox::hashRefPtr<const ConnectionDescription> >
49 : MCNodes;
50 472 : MCNodes mcNodes; // first node using a multicast connection
51 :
52 : typedef std::set<ConstConnectionDescriptionPtr> MCSet;
53 472 : MCSet mcSet; // multicast connection is added
54 :
55 355 : for (Nodes::const_iterator i = nodes.begin(); i != nodes.end(); ++i)
56 : {
57 238 : NodePtr node = *i;
58 238 : ConnectionPtr connection = node->getConnection(true /* preferMC */);
59 119 : LBASSERT(connection);
60 119 : if (!connection)
61 0 : continue;
62 :
63 119 : if (connection->isMulticast())
64 : {
65 0 : ConstConnectionDescriptionPtr desc = connection->getDescription();
66 0 : if (mcSet.find(desc) != mcSet.end()) // already added
67 0 : continue;
68 :
69 0 : MCNodes::iterator j = mcNodes.find(desc);
70 0 : if (j == mcNodes.end())
71 : {
72 : // first appearance of multicast connection
73 0 : mcNodes[desc] = node;
74 0 : continue;
75 : }
76 :
77 0 : mcSet.insert(desc); // mark as added
78 0 : mcNodes.erase(j);
79 : }
80 :
81 119 : result.push_back(connection);
82 : }
83 :
84 : // Add unicast connections for multicast node connections seen only once
85 236 : for (MCNodes::iterator i = mcNodes.begin(); i != mcNodes.end(); ++i)
86 : {
87 0 : ConnectionPtr connection = i->second->getConnection();
88 0 : LBASSERT(connection.isValid());
89 :
90 0 : if (connection.isValid())
91 0 : result.push_back(connection);
92 : }
93 472 : return result;
94 : }
95 : }
96 :
97 : #endif // CO_CONNECTIONS_H
|