I need to manage lists of executables Id. Each executable belongs to a capacity (obviously the list of capacities in the code is just an example).
For every capacity we need to be able to find the first executableId which is Available (ie not doing any treatment) and to modify the availability of an executable Id. executable Ids can be seen as the process Id.
Is the idea of using map a good one? Or should I use two vectors for every capacities, one for the executables Availables and the other for the executables In progress?
#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
constexpr int ERROR = -1;
enum class Disponibility {
Available,
In_Progress,
};
enum class Capacity {
TRT_1,
TRT_2,
TRT_3,
};
std::ostream& operator<<(std::ostream &os, const Capacity & cap) {
switch(cap) {
case Capacity::TRT_1:
os << "TRT_1";
break;
case Capacity::TRT_2:
os << "TRT_2";
break;
case Capacity::TRT_3:
os << "TRT_3";
default:
break;
}
return os;
}
std::ostream& operator<<(std::ostream &os, const Disponibility & dispo) {
switch(dispo) {
case Disponibility::Available:
os << "Available";
break;
case Disponibility::In_Progress:
os << "In_Progress";
break;
default:
break;
}
return os;
}
/*
Initialize by passing a vector of all capacities the Manager should deal with
Ideas : - Allow constructor to be done with any iterable container ?
*/
class ManageListExe {
public:
ManageListExe(const std::vector<Capacity> &listCap)
{
for(const auto cap : listCap)
{
listExeByCapacity[cap] = {};
}
}
template<typename T>
void updateListExe(const Capacity cap, const T& listExecutableId)
{
//Add executable Id when not in list
for(const auto exeId: listExecutableId)
{
if(listExeByCapacity[cap].find(exeId) == listExeByCapacity[cap].end())
{
addExeFromCap(cap, exeId);
}
}
//Remove from listExeByCapacity executableId which are not anymore in listExecutableId
for(const auto val: listExeByCapacity[cap])
{
if(std::find(listExecutableId.cbegin(), listExecutableId.cend(), val.first) == listExecutableId.cend())
{
removeExeFromCap(cap, val.first);
}
}
}
int getFirstExeAvailable(const Capacity cap)
{
//return first exe available from the list
for(const auto val: listExeByCapacity[cap])
{
if(val.second == Disponibility::Available)
{
return val.first;
}
}
return ERROR;
}
void changeDisponibility(const Capacity cap, const int executableId, const Disponibility dispo)
{
listExeByCapacity[cap][executableId] = dispo;
}
void printListExe()
{
for(const auto listByCap:listExeByCapacity)
{
for(const auto listExe:listByCap.second)
{
std::cout << "Capacity : " << listByCap.first
<< ", ExecutableId : " << listExe.first << " : "
<< listExe.second << "\n";
}
}
}
void printListExeFromCapacity(const Capacity cap)
{
std::cout << "Capacity : " << cap << "\n";
for(const auto listExe:listExeByCapacity[cap])
{
std::cout << "ExecutableId : " << listExe.first << " : "
<< listExe.second << "\n";
}
}
private:
void addExeFromCap(const Capacity cap, const int executableId)
{
listExeByCapacity[cap][executableId] = Disponibility::Available;
}
void removeExeFromCap(const Capacity cap, const int executableId)
{
listExeByCapacity[cap].erase(executableId);
}
std::map<Capacity, std::map<int, Disponibility>> listExeByCapacity;
};
int main()
{
std::cout << "Start tests" << std::endl;
//Test creating Manager
std::vector<Capacity> vectorCapacity = {Capacity::TRT_1, Capacity::TRT_2};
ManageListExe managerList(vectorCapacity);
//Test updating capacities
std::vector<int> listExe = {1,2,0};
managerList.updateListExe(Capacity::TRT_1, listExe);
listExe.push_back(4);
managerList.updateListExe(Capacity::TRT_1, listExe);
std::cout << "---\nWe should see executableId 0,1,2,4 from TRT_1 : " << std::endl;
managerList.printListExeFromCapacity(Capacity::TRT_1);
//Test with 2 capacities
managerList.updateListExe(Capacity::TRT_2, listExe);
std::cout << "---\nWe should see executableId 0,1,2,4 from TRT_1 and TRT_2 : " << std::endl;
managerList.printListExe();
//Test changing one disponibility
managerList.changeDisponibility(Capacity::TRT_1, 0, Disponibility::In_Progress);
std::cout << "---\nWe should see executableId 0,1,2,4 from TRT_1 and executable 0 should be in progress : " << std::endl;
managerList.printListExeFromCapacity(Capacity::TRT_1);
//Test remove one element in list
listExe.pop_back();
managerList.updateListExe(Capacity::TRT_1, listExe);
std::cout << "---\nWe should see executableId 0,1,2 from TRT_1 and 0,1,2,4 from TRT_2 : " << std::endl;
managerList.printListExe();
//Test Getting first executableId Available
int firstExeAvailable = managerList.getFirstExeAvailable(Capacity::TRT_1);
std::cout << "First executableId available from capacity TRT_1 (should be 1) : " << firstExeAvailable << std::endl;
return 0;
}