diff --git a/FunctionSpace/PermutationTree.cpp b/FunctionSpace/PermutationTree.cpp index fb6fa539d847905bf0751ae425d524bbe0731135..d9b916adbfc6935b5cde7805e9e3d6ae5367e6a6 100644 --- a/FunctionSpace/PermutationTree.cpp +++ b/FunctionSpace/PermutationTree.cpp @@ -37,45 +37,34 @@ PermutationTree::PermutationTree(const vector<size_t>& refSequence){ leaf[i]->leafId = i; } -PermutationTree::PermutationTree(string path){ +PermutationTree::PermutationTree(const char* stream){ + // Populate from stream + populateFromStream(stream); +} + +PermutationTree::PermutationTree(const string& path){ // Read file // // Open Stream ifstream input; input.exceptions(std::ifstream::failbit | std::ifstream::badbit); input.open(path.c_str(), std::ifstream::binary); - // Alloc stream for header - char* stream = new char[3 * sizeof(size_t)]; - - // Read header - size_t uSize; // Unlink struct size - size_t nSize; // Total size for unlink struct - - input.read(stream, 3 * sizeof(size_t)); + // Get size of stream (go to stream end) + input.seekg(0, std::ifstream::end); + const size_t size = input.tellg(); - memcpy(&uSize, stream + 0 * sizeof(size_t), sizeof(size_t)); - memcpy(&nextNodeId, stream + 1 * sizeof(size_t), sizeof(size_t)); - memcpy(&sequenceSize, stream + 2 * sizeof(size_t), sizeof(size_t)); + // Reset stream possition + input.seekg(0, std::ifstream::beg); - // Alloc stream for unlink struct - delete[] stream; - nSize = uSize * nextNodeId; - stream = new char[nSize]; + // Alloc byte stream & Read file + char* stream = new char[size]; + input.read(stream, size); - // Read unlink struct & close - input.read(stream, nSize); - input.close(); - - // Unserialize unlink struct - vector<unlink_t> unlink(nextNodeId); - for(size_t i = 0; i < nextNodeId; i++) - unserialize(stream + (i * uSize), &unlink[i]); + // Populate from stream + populateFromStream(stream); // Free stream delete[] stream; - - // Regenerate Tree // - rebuild(unlink); } void PermutationTree::populate(node_t* node, @@ -126,7 +115,27 @@ void PermutationTree::populate(node_t* node, listOfLeaf.push_back(node); } -void PermutationTree::unserialize(char* stream, unlink_t* unlink){ +void PermutationTree::populateFromStream(const char* stream){ + // Header Size + const size_t hSize = headerSize(); + + // Read header + size_t uSize; // Unlink struct size + + memcpy(&uSize, stream + 0 * sizeof(size_t), sizeof(size_t)); + memcpy(&nextNodeId, stream + 1 * sizeof(size_t), sizeof(size_t)); + memcpy(&sequenceSize, stream + 2 * sizeof(size_t), sizeof(size_t)); + + // Unserialize unlink struct + vector<unlink_t> unlink(nextNodeId); + for(size_t i = 0; i < nextNodeId; i++) + unserialize(stream + hSize + (i * uSize), &unlink[i]); + + // Regenerate Tree // + rebuild(unlink); +} + +void PermutationTree::unserialize(const char* stream, unlink_t* unlink){ // Some padding data // const size_t nxtChoiceStart = 2 * sizeof(size_t); const size_t fatherIdStart = nxtChoiceStart + sequenceSize * sizeof(size_t); @@ -352,7 +361,7 @@ string PermutationTree::toString(void) const{ return stream.str(); } -void PermutationTree::serialize(string path) const{ +std::pair<size_t, char*> PermutationTree::serialize(void) const{ // Enumerate Nodes // list<node_t*> node; enumerate(root, node); @@ -367,18 +376,19 @@ void PermutationTree::serialize(string path) const{ const size_t uSize = unlinkSize(&tmp); // Unlink struct size const size_t nNode = node.size(); // Number of node/unlink struct const size_t nSize = uSize * nNode; // Total size for unlink struct + const size_t sSize = hSize + nSize; // Stream size - // Alloc byte stream - char* stream = new char[nSize + hSize]; - for(size_t i = 0; i < nSize + hSize; i++) + // Alloc byte Stream + char* stream = new char[sSize]; + for(size_t i = 0; i < sSize; i++) stream[i] = 0; - // Write header + // Write header in Stream memcpy(stream + 0 * sizeof(size_t), &uSize, sizeof(size_t)); memcpy(stream + 1 * sizeof(size_t), &nNode, sizeof(size_t)); memcpy(stream + 2 * sizeof(size_t), &sequenceSize, sizeof(size_t)); - // Write unlinked node + // Write unlinked node in Stream list<node_t*>::iterator it = node.begin(); for(size_t i = 0; i < nNode; i++, it++){ @@ -386,15 +396,23 @@ void PermutationTree::serialize(string path) const{ serialize(stream + hSize + (i * uSize), &tmp); } + // Return Stream & its size + return pair<size_t, char*>(sSize, stream); +} + +void PermutationTree::serialize(const string& path) const{ + // Serialize into byte Stream + std::pair<size_t, char*> stream = serialize(); + // Write byte stream ofstream output; output.exceptions(std::ofstream::failbit | std::ofstream::badbit); output.open(path.c_str(), std::ofstream::binary); - output.write(stream, nSize + hSize); + output.write(stream.second, stream.first); output.close(); // Free - delete[] stream; + delete[] stream.second; } void PermutationTree::enumerate(node_t* node, std::list<node_t*>& listOfNode){ diff --git a/FunctionSpace/PermutationTree.h b/FunctionSpace/PermutationTree.h index 8258147c48d6d0b78c8746c985e1ce948e1e1740..ce19b5b1e9e6d52dd8c56065686ffcfd619b4871 100644 --- a/FunctionSpace/PermutationTree.h +++ b/FunctionSpace/PermutationTree.h @@ -65,7 +65,8 @@ class PermutationTree{ public: PermutationTree(const std::vector<size_t>& refSequence); - PermutationTree(std::string path); + PermutationTree(const char* stream); + PermutationTree(const std::string& path); ~PermutationTree(void); size_t getSequenceSize(void) const; @@ -83,11 +84,13 @@ class PermutationTree{ std::vector<std::pair<size_t, size_t> > getAllTagsCount(void) const; std::string toString(void) const; - void serialize(std::string path) const; + std::pair<size_t, char*> serialize(void) const; + void serialize(const std::string& path) const; private: void populate(node_t* node, std::list<node_t*>& listOfLeaf); - void unserialize(char* stream, unlink_t* unlink); + void populateFromStream(const char* stream); + void unserialize(const char* stream, unlink_t* unlink); void rebuild(std::vector<unlink_t>& unlink); static node_t* copy(unlink_t* unlink); @@ -112,13 +115,20 @@ class PermutationTree{ Instanciates a new PermutationTree build on the given vector ** + @fn PermutationTree::PermutationTree(const char* stream) + @param stream A byte stream + + Instanciates a new PermutationTree by loading the given byte stream + + @see PermutationTree:serialize(char*) + ** + @fn PermutationTree::PermutationTree(std::string path) @param path A file path - Instanciates a new PermutationTree by loading the - serialized PermutationTree given in path + Instanciates a new PermutationTree by loading the file given in path - @see PermutationTree:serialize() + @see PermutationTree:serialize(const std::string&) ** @fn PermutationTree::~PermutationTree @@ -185,7 +195,16 @@ class PermutationTree{ @return Returns a string describing this PermutationTree ** - @fn PermutationTree::serialize + @fn PermutationTree::serialize(void) + + Serialize this PermutationTree into a byte stream + + @return Returns a pair such that: + @li The first entry is stream size + @li the second entry is a pointer to the allocated stream + ** + + @fn PermutationTree::serialize(const std::string&) @param path A file path Serialize this PermutationTree into the given file path