-
Notifications
You must be signed in to change notification settings - Fork 0
/
ring.cc
176 lines (143 loc) · 4.77 KB
/
ring.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#include "CNode.h"
#include "loggers.h"
#include <string>
#include <thread>
#include <vector>
#include <sstream>
#include <numeric>
using namespace RING;
using namespace std;
struct SCommandLineArgs
{
enum class ELoggerType
{
MessageLogger,
MessageCountLogger
};
enum class EInputType
{
FromFile,
FromCommandLine
};
SCommandLineArgs(int p_argc, char* p_argv[])
: m_loggerType(GetLoggerType(p_argv[1]))
, m_inputType(GetInputType(p_argv[2]))
{
switch (m_inputType)
{
case EInputType::FromFile:
ReadTopologiesFromFile(p_argv[3]);
break;
case EInputType::FromCommandLine:
vector<unsigned> ids;
for (auto i = 3u; i < p_argc; ++i)
ids.push_back(stoul(p_argv[i]));
m_topologies.push_back(ids);
break;
}
}
static ELoggerType GetLoggerType(const string& p_loggerType)
{
if (p_loggerType == "message_count")
return ELoggerType::MessageCountLogger;
else if (p_loggerType == "message_logger")
return ELoggerType::MessageLogger;
throw exception();
}
static EInputType GetInputType(const string& p_inputType)
{
if (p_inputType == "from_file")
return EInputType::FromFile;
else if (p_inputType == "command_line")
return EInputType::FromCommandLine;
throw exception();
}
static unsigned GetArgsNum(int p_argc)
{ return p_argc - s_numOfArgsBeforeInput; }
static bool CheckArgsNum(int p_argc)
{
if (p_argc >= s_minArgs)
return true;
cout << "There are no enough args for running!" << endl;
cout << "[message_logger/message_count] [from_file/command_line] [filename/topology]" << endl;
return false;
}
void ReadTopologiesFromFile(const string& p_filename)
{
// FIXME error if something not good
ifstream infile(p_filename);
auto numberOfTests = 0u;
string line;
while (getline(infile, line))
{
stringstream ss(line);
vector<unsigned> ids;
string tmp;
while(getline(ss, tmp, ','))
ids.push_back(stoul(tmp));
m_topologies.push_back(ids);
}
}
static const unsigned s_numOfArgsBeforeInput = 2;
static const unsigned s_minArgs = 4;
const ELoggerType m_loggerType;
const EInputType m_inputType;
vector<vector<unsigned>> m_topologies;
};
int main(int argc, char* argv[])
{
if (!SCommandLineArgs::CheckArgsNum(argc))
return 0;
SCommandLineArgs args(argc, argv);
const auto ip = "127.0.0.1";
const auto defaultPortNum = 30000u;
const auto getAddress = [&](unsigned p_port)
{
stringstream ss;
ss << ip << ":" << p_port;
return ss.str();
};
const auto getLogger = [&](unsigned p_nodeCount) -> shared_ptr<CLoggerBase>
{
if (args.m_loggerType == SCommandLineArgs::ELoggerType::MessageCountLogger)
return make_shared<CMessageCountLogger>(p_nodeCount);
static const auto getLogFilename = []()
{
static auto num = 0u;
stringstream ss;
ss << "log-" << num;
return ss.str();
};
return make_shared<CLogger>(getLogFilename());
};
for (const auto topology : args.m_topologies)
{
cout << accumulate(topology.begin(), topology.end(), string{},
[](string& p_result, const unsigned& p_elem) -> decltype(auto)
{ return p_result += to_string(p_elem) + " "; }) << endl;
const auto nodeCount = topology.size();
auto logger = getLogger(nodeCount);
vector<unique_ptr<CNode> > ring;
for (auto i = 0u; i < nodeCount; ++i)
{
const auto rightOrderId = (i + 1) % nodeCount;
const auto leftOrderId = (i + nodeCount - 1) % nodeCount;
ring.emplace_back(make_unique<CNode>(topology[i],
logger,
getAddress(defaultPortNum + i), // right skeleton addr
getAddress(defaultPortNum + i + nodeCount), // left skeleton addr
CUnit::SNeighbour{topology[rightOrderId], getAddress(defaultPortNum + rightOrderId)}, // right neighbor
CUnit::SNeighbour{topology[leftOrderId], getAddress(defaultPortNum + leftOrderId + nodeCount)})); // left neighbor
}
// starting skeletons
for (auto& node : ring)
node->StartSkeleton();
// starting stubs
for (auto& node : ring)
node->StartStub();
// starting stubs
for (auto& node : ring)
node->RunHDAEagerLE();
}
return 0;
}