Commit a5a9d20c authored by lu43jih's avatar lu43jih
Browse files

Implementation for parsing compressed node name formats plus small comment fixes

parent 73fa41e2
......@@ -2,7 +2,7 @@
* ConfiguratorTemplate.h
*
* Created on: 13.01.2018
* Author: Micha Mueller
* Author: Micha Mueller, Carla Guillen
*/
#ifndef SRC_CONFIGURATORTEMPLATE_H_
......@@ -47,6 +47,11 @@ protected:
using SB_Ptr = std::shared_ptr<SBase>;
using SG_Ptr = std::shared_ptr<SGroup>;
const char COMMA = ',';
const char OPEN_SQBRKET = '[';
const char CLOSE_SQBRKET = ']';
const char DASH = '-';
public:
ConfiguratorTemplate() :
_entityName("INVALID"),
......@@ -753,6 +758,192 @@ protected:
return cpus;
}
/**
* Tries to parse the given compressedList as node names. On success, the specified numbers will be inserted
* into the set nodeNames, and true is returned. On failure, false is returned. A set is used to maintain uniqueness
* and an ascending order among the numbers although this is not strictly required.
*
* @param compressedList String which specifies a range of node names (e.g. "a[2-4]b[1-3]c[4-7]")
* @return true if parsed successfully, false otherwise
*/
bool tokenizeCompressedHostList(const std::string& compressedList, std::set<std::string>& nodeNames){
int count = 0;
std::string token;
std::stringstream iss(compressedList);
std::stringstream tokenBuffer;
while (getline(iss, token, COMMA)) { //put in token contents until a comma "," is found
std::string::size_type pos_sqbr = token.find(OPEN_SQBRKET);
if (pos_sqbr != std::string::npos && tokenBuffer.rdbuf()->in_avail() == 0){ //found a '[' at the first trial
//for every open bracket we should have a closing bracket
size_t openbrackets = std::count(token.begin(), token.end(), OPEN_SQBRKET);
size_t closedbrackets = std::count(token.begin(), token.end(), CLOSE_SQBRKET);
if(openbrackets != closedbrackets){ // (this case token looks like this: "a[2-4" )
//get the next chunk to process in the geline
tokenBuffer << token; //first time no comma needed
} else { //yuhuu token found with compression (this case token looks like this: "a[2-4]b[1-3]c[4-7]" )
if(!parseCompressedToken(token, nodeNames)){
LOG(warning) << " Nodes could not be parsed!";
return false;
}
//http://stackoverflow.com/questions/20731/in-c-how-do-you-clear-a-stringstream-variable
tokenBuffer.str(std::string()); //reset joinToNext we found the entire token.
}
} else if(pos_sqbr != std::string::npos && tokenBuffer.rdbuf()->in_avail() != 0 ){ //'[' found and buffer has something
tokenBuffer << COMMA << token;
token = tokenBuffer.str();
//for every open bracket we should have a closing bracket
size_t openbrackets = std::count(token.begin(), token.end(), OPEN_SQBRKET);
size_t closedbrackets = std::count(token.begin(), token.end(), CLOSE_SQBRKET);
if(openbrackets == closedbrackets){ //yuhuu token found (this case token looks like this: "a[2-4]b[1,3]" )
if(!parseCompressedToken(token, nodeNames)) {
LOG(warning) << " Nodes could not be parsed!";
return false;
}
tokenBuffer.str(std::string()); //reset joinToNext we found the entire token.
} //else get the next chunk to process in the geline (this case looks token like this: "a[2,4]b[1," )
} else if(pos_sqbr == std::string::npos && tokenBuffer.rdbuf()->in_avail() != 0 ){ //no '[' found and buffer has something
std::string::size_type pos_closesqbr = token.find(CLOSE_SQBRKET);
if(pos_closesqbr == std::string::npos){
//(this case looks like this, buffer: "a[2" and token "4" joined to "a[2,4 )
tokenBuffer << COMMA << token;
} else {
tokenBuffer << COMMA << token; //(this case looks like this, buffer: "a[2" and token "4]b1" joined to "a[2,4]b1 )
token = tokenBuffer.str();
if(!parseCompressedToken(token, nodeNames)) return false;
tokenBuffer.str(std::string()); //reset joinToNext we found the entire token.
}
} else { //no squared brackets found and buffer is empty (no compression)
nodeNames.insert(token);
count++;
}
}
return nodeNames;
}
bool parseCompressedToken(std::string token, std::set<std::string>&nodeNames){
std::string::size_type closing_bracket = token.find(CLOSE_SQBRKET);
std::stringstream iss(token);
std::stringstream token_ss;
std::map<int, std::vector<std::string> > levelPartToNodeNameparts;
int levels = 0;
while (getline(iss, token, CLOSE_SQBRKET)) { //put in token contents until a "]" is found
token_ss << token << CLOSE_SQBRKET;
std::vector<std::string> nodename_parts;
std::string token_part= token_ss.str();
if(parseTokenPart(nodename_parts, token_part) ){
levelPartToNodeNameparts[levels] = nodename_parts;
levels++;
}
token_ss.str(std::string());
}
if(levels < 1) return false;
//cross product of all levels
std::vector<std::string> nodes_comb = levelPartToNodeNameparts[0];
for (unsigned int it = 1; it < levels; ++it) {
std::vector<std::string> nodes_parts1 = nodes_comb;
std::vector<std::string> nodes_parts2 = levelPartToNodeNameparts[it];
nodes_comb.clear();
for (int i = 0; i < nodes_parts1.size(); ++i) {
for (int j = 0; j < nodes_parts2.size(); ++j) {
nodes_comb.push_back(nodes_parts1[i] + nodes_parts2[j]);
}
}
}
nodeNames.insert(nodes_comb.begin(), nodes_comb.end());
return true;
}
bool parseTokenPart(std::vector<std::string> &names_parts, std::string &token){
//first get the "stem" and bracketlist from mpp2r03c05s[02,05,07,11-15]
// stem = mpp2r03c05s,
// bracketlists = 02,05,07,11-15
std::string::size_type sqrbrOpen = token.find(OPEN_SQBRKET);
std::string stem = token.substr(0, sqrbrOpen);
std::string bracketlists = token.substr(sqrbrOpen+1);
//get the comma separated tokens mpp2r03c05s[02,05,07,11-15] ==> tokenize to "02","05","07", "11-15"
std::stringstream iss(bracketlists);
std::string subtoken;
std::vector<int> nodeIntParts;
int decimal_positions =0;
while (getline(iss, subtoken, COMMA)) {
//find if it is a simple number or a list
std::string::size_type dash = subtoken.find(DASH);
if(dash != std::string::npos){ //dash found
std::string minStr = subtoken.substr(0,dash);
std::string maxStr = subtoken.substr(dash+1);
int minIntPart;
try {
minIntPart= std::stoi(minStr.c_str());
} catch (std::exception& e) {
LOG(warning) << "\t\tException when parsing {" << minStr << "}";
LOG(warning) << "\t\t" << e.what();
return false;
}
int maxIntPart;
try {
maxIntPart= std::stoi(maxStr.c_str());
} catch (std::exception& e) {
LOG(warning) << "\t\tException when parsing {" << maxStr << "}";
LOG(warning) << "\t\t" << e.what();
return false;
}
std::string::size_type closingbr = maxStr.find(CLOSE_SQBRKET);
if(closingbr != std::string::npos){ //remove closing bracket
maxStr = maxStr.substr(0, closingbr);
}
if(maxStr.length() > decimal_positions){
decimal_positions = maxStr.length();
}
if(maxIntPart > minIntPart){
for (int i = minIntPart; i < maxIntPart+1; ++i) {
nodeIntParts.push_back(i);
}
} else {
return false; //we are parsing such a case: [10-2] error or simply reverse the order?
}
} else { //dash not found
std::string::size_type closingbr = subtoken.find(CLOSE_SQBRKET);
if(closingbr != std::string::npos){ //remove closing bracket
subtoken = subtoken.substr(0, subtoken.size()-1);
}
if(subtoken.length() > decimal_positions){
decimal_positions = subtoken.length();
}
int nodePartInt;
try {
nodePartInt = std::stoi(subtoken.c_str());
} catch (std::exception& e) {
LOG(warning) << "\t\tException when parsing {" << subtoken << "}";
LOG(warning) << "\t\t" << e.what();
return false;
}
nodeIntParts.push_back(nodePartInt);
}
}
for (auto nodeEnd: nodeIntParts) {
if(nodeEnd < 0){
return false;
}
std::stringstream nodeNameBuilder;
nodeNameBuilder << stem;
if(nodeEnd < pow(10, decimal_positions-1)){
int powers = 0;
if(nodeEnd==0){
powers = 1;
} else {
powers = static_cast<int>(log10(nodeEnd)) + 1;
}
for ( int i = 0; i < decimal_positions - powers; ++ i) {
nodeNameBuilder << "0";
}
}
nodeNameBuilder << nodeEnd;
names_parts.push_back(nodeNameBuilder.str());
}
return true;
}
std::string _entityName;
std::string _groupName;
std::string _baseName;
......
/*
* gpfsmonConfigurator.cpp
* GpfsmonConfigurator.cpp
*
* Created on: 26.11.2018
* Author: Carla Guillen
......@@ -37,7 +37,7 @@ void GpfsmonConfigurator::sensorBase(GpfsmonSensorBase& s, CFG_VAL config) {
} else {
LOG(warning) << " metric \"" << val.second.data() << "\" not known.";
}
} else if(boost::iequals(val.first, "nodeName")){
} else if(boost::iequals(val.first, "nodeName")){ //todo change this to parse a compressed format (mpp2[2,3-4]r[01,03]c[13-90])
s.setNodeName(val.second.data());
}
}
......
/*
* gpfsmonConfigurator.h
* GpfsmonConfigurator.h
*
* Created on: 26.11.2018
* Author: Carla Guillen
......
......@@ -29,17 +29,18 @@ struct GPFSSensorCompare {
GpfsmonSensorGroup::GpfsmonSensorGroup(const std::string& name) :
SensorGroupTemplate(name) {
createTempFile();
_data.resize(GPFS_METRIC::SIZE);
}
GpfsmonSensorGroup& GpfsmonSensorGroup::operator=(const GpfsmonSensorGroup& other){
SensorGroupTemplate<GpfsmonSensorBase>::operator=(other);
_data = other._data; //copy of vectors
//no need to copy _data
return *this;
}
GpfsmonSensorGroup::GpfsmonSensorGroup(const GpfsmonSensorGroup& other):
SensorGroupTemplate<GpfsmonSensorBase>(other){
_data = other._data;
_data.resize(GPFS_METRIC::SIZE);
}
GpfsmonSensorGroup::~GpfsmonSensorGroup() {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment