forked from mvolotov/KursSMO
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcomputingsystem.cpp
119 lines (92 loc) · 5.08 KB
/
computingsystem.cpp
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
#include "computingsystem.h"
#include "serverprogramm.h"
#include "constants.h"
#include "math.h"
#include <algorithm>
#include "cpplinq.hpp"
using namespace cpplinq;
ComputingSystem::ComputingSystem()
{
}
ComputingSystem::Simulate(DistributionType distributionType = Liniar){
ComputingSystemStatistics statistic = new ComputingSystemStatistics();
double timeTillNextProgrammLinear = 0;
auto popupProbabilityExp = GetExpProbability(Constants::ProgrammPopupTime::ExpLambda, Constants::SimulationStep);
double elapsedExp = 0;
for (double i = 0; i <= Constants::SimulationTime; i += Constants::SimulationStep){
std::for_each(programms.begin(), programms.end(), [](ServerProgramm s) {s.Update(Constants::SimulationStep);});
if(distributionType == Liniar){
if(timeTillNextProgrammLinear <= 0){
ServerProgramm serverProgramm = new ServerProgramm(Liniar, GetRandomNumber(Constants::ProgrammExecutionTime::LinearMinTime, Constants::ProgrammExecutionTime::LinearMaxTime));
programms.push_back(serverProgramm);
timeTillNextProgrammLinear = GetRandomNumber(Constants::ProgrammPopupTime::LinearMinTime, Constants::ProgrammPopupTime::LinearMaxTime);
statistic::TotalProgrammsAdded++;
}
timeTillNextProgrammLinear -= Constants::SimulationStep;
}else if(distributionType == Exponential){
if(popupProbabilityExp > GetRandomNumber(0,1)){
ServerProgramm serverProgramm = new ServerProgramm(Exponential, GetRandomNumber(Constants::ProgrammExecutionTime::LinearMinTime, Constants::ProgrammExecutionTime::LinearMaxTime));
programms.push_back(serverProgramm);
statistic::TotalProgrammsAdded++;
}
}
auto countOfAwaiting = from(programms)
>> where([](ServerProgramm s) {return s.Status == ServerProgramm::ProgrammStatus::AwaitingExecution;})
>> count();
int freeServersCount = Constants::ServersCount - countOfAwaiting;
for (std::list<programms>::iterator it=programms.begin(); it != programms.end(); ++it){
if(it->Status == ServerProgramm::ProgrammStatus::AwaitingExecution){
it->Status = ServerProgramm::ProgrammStatus::Execution;
}
}
// from(programms)
// >> where([](ServerProgramm s) {return s.Status == ServerProgramm::ProgrammStatus::AwaitingExecution;})
// >> take(freeServersCount)
// >> to_list();
auto countOverFlow = from(programms)
>> where([](ServerProgramm s) {return s.Status == ServerProgramm::ProgrammStatus::AwaitingExecution;})
>> count();
auto overflowCount = countOverFlow - Constants::BufferSize;
if (overflowCount > 0){
for (std::list<programms>::iterator it=programms.begin(); it != programms.end(); ++it){
if(*it.Status == ServerProgramm::ProgrammStatus::AwaitingExecution){
*it.Status = ServerProgramm::ProgrammStatus::Discarded;
}
}
programms.Where(x => x.Status == ServerProgramm.ProgrammStatus.AwaitingExecution).Take(overflowCount).ToList()
.ForEach(x => x.Status = ServerProgramm.ProgrammStatus.Discarded);
}
//сбор статистики
statistic.SnapShots.push_back(new SnapShot()
{
BufferItemsCount = from(programms)
>> where([](ServerProgramm s) {return s.Status == ServerProgramm::ProgrammStatus::AwaitingExecution;})
>> count();
ExecutingCount =from(programms)
>> where([](ServerProgramm s) {return s.Status == ServerProgramm::ProgrammStatus::Execution;})
>> count();
});
//удаляем из листа программ не обработанные и выполненные программы для оптимизации скорости поиска по листу в следующих итерациях
for (std::list<programms>::iterator it=programms.begin(); it != programms.end(); ++it){
if (it->Status == ServerProgramm.ProgrammStatus.Executed) {
statistic.ExecutedProgrammsCount++;
it = programms.erase(it);
finishedProgramms.push_back(it);
} else if(it->Status == ServerProgramm.ProgrammStatus.Discarded){
statistic.DiscardedProgrammsCount++;
it = programms.erase(it);
finishedProgramms.push_back(it);
}
}
}
finishedProgramms.AddRange(programms);
statistic.programms = finishedProgramms;
return statistic;
}
double ComputingSystem::GetExpProbability(double lambda, double time){
return lambda < 0 ? 0 :
1 - (exp(-lambda*time));
}
double ComputingSystem::GetRandomNumber(double min, double max){
return (double)(rand())/RAND_MAX*(max - min) + min;
}