293 lines
9.4 KiB
C
293 lines
9.4 KiB
C
|
|
#pragma once
|
||
|
|
#include <string>
|
||
|
|
#include <map>
|
||
|
|
#include <set>
|
||
|
|
#include "Array.h"
|
||
|
|
|
||
|
|
#define MAP std::map
|
||
|
|
#define SET std::set
|
||
|
|
#define VECTOR std::vector
|
||
|
|
#define STRING std::string
|
||
|
|
#define PAIR std::pair
|
||
|
|
|
||
|
|
namespace Distribution
|
||
|
|
{
|
||
|
|
template<typename vType>
|
||
|
|
class Arrays
|
||
|
|
{
|
||
|
|
private:
|
||
|
|
unsigned nextVertexNum;
|
||
|
|
|
||
|
|
MAP<Array*, VECTOR<vType>> numVertsInGraph;
|
||
|
|
MAP<STRING, Array*> arraysByName;
|
||
|
|
SET<Array*> arrays;
|
||
|
|
VECTOR<STRING> arrayNameByVertex;
|
||
|
|
VECTOR<PAIR<int, Array*>> arrayDimInfoByVertex;
|
||
|
|
public:
|
||
|
|
Arrays() { nextVertexNum = 0; }
|
||
|
|
|
||
|
|
Arrays(const Arrays ©)
|
||
|
|
{
|
||
|
|
nextVertexNum = copy.nextVertexNum;
|
||
|
|
numVertsInGraph = copy.numVertsInGraph;
|
||
|
|
arraysByName = copy.arraysByName;
|
||
|
|
arrays = copy.arrays;
|
||
|
|
arrayNameByVertex = copy.arrayNameByVertex;
|
||
|
|
arrayDimInfoByVertex = copy.arrayDimInfoByVertex;
|
||
|
|
}
|
||
|
|
|
||
|
|
void UpdateLinks(const MAP<Array*, Array*> &oldNewArrays)
|
||
|
|
{
|
||
|
|
SET<Array*> newArrays;
|
||
|
|
for (auto &array : arrays)
|
||
|
|
newArrays.insert(oldNewArrays.find(array)->second);
|
||
|
|
arrays = newArrays;
|
||
|
|
|
||
|
|
for (auto &elem : arraysByName)
|
||
|
|
elem.second = oldNewArrays.find(elem.second)->second;
|
||
|
|
|
||
|
|
for (auto &elem : arrayDimInfoByVertex)
|
||
|
|
elem.second = oldNewArrays.find(elem.second)->second;
|
||
|
|
|
||
|
|
MAP<Array*, VECTOR<vType>> newNumVertsInGraph;
|
||
|
|
for (auto &elem : numVertsInGraph)
|
||
|
|
newNumVertsInGraph.insert(std::make_pair(oldNewArrays.find(elem.first)->second, elem.second));
|
||
|
|
numVertsInGraph = newNumVertsInGraph;
|
||
|
|
}
|
||
|
|
|
||
|
|
void cleanData()
|
||
|
|
{
|
||
|
|
nextVertexNum = 0;
|
||
|
|
numVertsInGraph.clear();
|
||
|
|
arraysByName.clear();
|
||
|
|
arrays.clear();
|
||
|
|
arrayNameByVertex.clear();
|
||
|
|
arrayDimInfoByVertex.clear();
|
||
|
|
}
|
||
|
|
|
||
|
|
int AddArrayToGraph(Array *array)
|
||
|
|
{
|
||
|
|
int status = 0;
|
||
|
|
auto foundIt = numVertsInGraph.find(array);
|
||
|
|
if (foundIt == numVertsInGraph.end())
|
||
|
|
{
|
||
|
|
const int dimSize = array->GetDimSize();
|
||
|
|
VECTOR<vType> vertexNum(dimSize);
|
||
|
|
|
||
|
|
for (int i = 0; i < dimSize; ++i)
|
||
|
|
{
|
||
|
|
vertexNum[i] = nextVertexNum + i;
|
||
|
|
|
||
|
|
STRING newName(array->GetName());
|
||
|
|
newName += "." + std::to_string(i);
|
||
|
|
arrayNameByVertex.push_back(newName);
|
||
|
|
arrayDimInfoByVertex.push_back(std::make_pair(i, array));
|
||
|
|
}
|
||
|
|
|
||
|
|
nextVertexNum += dimSize;
|
||
|
|
numVertsInGraph.insert(foundIt, make_pair(array, vertexNum));
|
||
|
|
arrays.insert(array);
|
||
|
|
arraysByName.insert(arraysByName.end(), make_pair(array->GetName(), array));
|
||
|
|
}
|
||
|
|
else
|
||
|
|
status = 1;
|
||
|
|
|
||
|
|
return status;
|
||
|
|
}
|
||
|
|
|
||
|
|
int GetVertNumber(Array *array, const int dimNum, vType &retVal) const
|
||
|
|
{
|
||
|
|
int err = 0;
|
||
|
|
auto foundIt = numVertsInGraph.find(array);
|
||
|
|
if (foundIt == numVertsInGraph.end())
|
||
|
|
err = -1;
|
||
|
|
else
|
||
|
|
{
|
||
|
|
const int maxDims = array->GetDimSize();
|
||
|
|
if (dimNum >= maxDims)
|
||
|
|
err = -1;
|
||
|
|
else
|
||
|
|
retVal = foundIt->second[dimNum];
|
||
|
|
}
|
||
|
|
return err;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
int GetAllVertNumber(const Array *array, std::vector<vType> &retVal) const
|
||
|
|
{
|
||
|
|
int err = 0;
|
||
|
|
auto foundIt = numVertsInGraph.find((Array*)array);
|
||
|
|
if (foundIt == numVertsInGraph.end())
|
||
|
|
err = -1;
|
||
|
|
else
|
||
|
|
retVal = foundIt->second;
|
||
|
|
return err;
|
||
|
|
}
|
||
|
|
|
||
|
|
int GetDimNumber(const Array *array, const vType vertexN, vType &retVal) const
|
||
|
|
{
|
||
|
|
int err = 0;
|
||
|
|
auto foundIt = numVertsInGraph.find((Array*)array);
|
||
|
|
if (foundIt == numVertsInGraph.end())
|
||
|
|
err = -1;
|
||
|
|
else
|
||
|
|
{
|
||
|
|
const int maxDims = array->GetDimSize();
|
||
|
|
for (int i = 0; i < maxDims; ++i)
|
||
|
|
{
|
||
|
|
if (foundIt->second[i] == vertexN)
|
||
|
|
{
|
||
|
|
retVal = i;
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
err = -1;
|
||
|
|
}
|
||
|
|
return err;
|
||
|
|
}
|
||
|
|
|
||
|
|
int GetNameByVertex(const vType vert, STRING &name) const
|
||
|
|
{
|
||
|
|
if (vert >= (vType)arrayNameByVertex.size())
|
||
|
|
return -1;
|
||
|
|
else
|
||
|
|
{
|
||
|
|
name = arrayNameByVertex[vert];
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
Array* GetArrayByVertex(const vType vert) const
|
||
|
|
{
|
||
|
|
STRING name;
|
||
|
|
int res = GetNameByVertex(vert, name);
|
||
|
|
Array *retVal = NULL;
|
||
|
|
|
||
|
|
if (res != -1)
|
||
|
|
{
|
||
|
|
int count = 0;
|
||
|
|
for (int k = (int)name.size() - 1; k >= 0; --k, ++count)
|
||
|
|
{
|
||
|
|
if (name[k] == '.')
|
||
|
|
{
|
||
|
|
name[k] = '\0';
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
name.resize(name.size() - count - 1);
|
||
|
|
retVal = GetArrayByName(name);
|
||
|
|
}
|
||
|
|
|
||
|
|
return retVal;
|
||
|
|
}
|
||
|
|
|
||
|
|
Array* GetArrayByName(const STRING &name) const
|
||
|
|
{
|
||
|
|
auto res = arraysByName.find(name);
|
||
|
|
if (res != arraysByName.end())
|
||
|
|
return res->second;
|
||
|
|
else
|
||
|
|
return NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
int GetInfoByVertex(const vType vertex, std::pair<int, Array*> &info) const
|
||
|
|
{
|
||
|
|
int err = (arrayDimInfoByVertex.size() >= vertex) ? 1 : 0;
|
||
|
|
if (arrayDimInfoByVertex.size() < vertex)
|
||
|
|
info = arrayDimInfoByVertex[vertex];
|
||
|
|
return err;
|
||
|
|
}
|
||
|
|
|
||
|
|
const SET<Array*>& GetArrays() const { return arrays; }
|
||
|
|
|
||
|
|
unsigned GetMaxVertexNum() const { return nextVertexNum; }
|
||
|
|
|
||
|
|
void SaveArraysToFile(FILE *file) const
|
||
|
|
{
|
||
|
|
if (file)
|
||
|
|
{
|
||
|
|
fprintf(file, "%d\n", nextVertexNum);
|
||
|
|
int count = numVertsInGraph.size();
|
||
|
|
fprintf(file, "%d\n", count);
|
||
|
|
for (auto &elem : numVertsInGraph)
|
||
|
|
{
|
||
|
|
fprintf(file, "%d\n", elem.first->GetArrayUniqKey().size());
|
||
|
|
fprintf(file, "%s\n", elem.first->GetArrayUniqKey().c_str());
|
||
|
|
int dimCount = elem.second.size();
|
||
|
|
fprintf(file, "%d\n", dimCount);
|
||
|
|
for (int z = 0; z < dimCount; ++z)
|
||
|
|
fprintf(file, "%d\n", elem.second[z]);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//load and check
|
||
|
|
bool LoadArraysFromFile(FILE *file, const SET<Array*> &currArrays, const int nextVertexNumOld)
|
||
|
|
{
|
||
|
|
bool status = true;
|
||
|
|
if (file)
|
||
|
|
{
|
||
|
|
char tmpChar;
|
||
|
|
MAP<STRING, Array*> keys;
|
||
|
|
for (auto &elem : currArrays)
|
||
|
|
keys.insert(std::make_pair(elem->GetArrayUniqKey(), elem));
|
||
|
|
|
||
|
|
fscanf(file, "%d", &nextVertexNum);
|
||
|
|
fscanf(file, "%c", &tmpChar);
|
||
|
|
if (nextVertexNumOld != nextVertexNum)
|
||
|
|
return false;
|
||
|
|
|
||
|
|
int count;
|
||
|
|
fscanf(file, "%d", &count);
|
||
|
|
fscanf(file, "%c", &tmpChar);
|
||
|
|
for (int i = 0; i < count; ++i)
|
||
|
|
{
|
||
|
|
int strLen = 0;
|
||
|
|
fscanf(file, "%d", &strLen);
|
||
|
|
fscanf(file, "%c", &tmpChar);
|
||
|
|
|
||
|
|
STRING uniqKey = "";
|
||
|
|
for (int k = 0; k < strLen; ++k)
|
||
|
|
{
|
||
|
|
char symb;
|
||
|
|
fscanf(file, "%c", &symb);
|
||
|
|
uniqKey += symb;
|
||
|
|
}
|
||
|
|
fscanf(file, "%c", &tmpChar);
|
||
|
|
|
||
|
|
int dimCount = 0;
|
||
|
|
fscanf(file, "%d", &dimCount);
|
||
|
|
fscanf(file, "%c", &tmpChar);
|
||
|
|
VECTOR<vType> tmp(dimCount);
|
||
|
|
for (int z = 0; z < dimCount; ++z)
|
||
|
|
{
|
||
|
|
fscanf(file, "%d", &(tmp[z]));
|
||
|
|
fscanf(file, "%c", &tmpChar);
|
||
|
|
}
|
||
|
|
|
||
|
|
auto found = keys.find(uniqKey);
|
||
|
|
if (found == keys.end())
|
||
|
|
{
|
||
|
|
status = false;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
numVertsInGraph.insert(std::make_pair(found->second, tmp));
|
||
|
|
arraysByName.insert(std::make_pair(found->second->GetName(), found->second));
|
||
|
|
arrays.insert(found->second);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
status = false;
|
||
|
|
return status;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
}
|
||
|
|
#undef MAP
|
||
|
|
#undef SET
|
||
|
|
#undef VECTOR
|
||
|
|
#undef STRING
|
||
|
|
#undef PAIR
|