implement "needs version" functionality for archiver

This commit is contained in:
Christopher Lackner 2019-01-23 10:19:43 +01:00
parent 0247b92a8a
commit f106404280
4 changed files with 65 additions and 10 deletions

View File

@ -153,6 +153,9 @@ namespace ngcore
const VersionInfo& GetVersion(const std::string& library) const VersionInfo& GetVersion(const std::string& library)
{ return version_map[library]; } { return version_map[library]; }
// only used for PyArchive
virtual void NeedsVersion(const std::string& library, const std::string& version) {}
// Pure virtual functions that have to be implemented by In-/OutArchive // Pure virtual functions that have to be implemented by In-/OutArchive
virtual Archive & operator & (double & d) = 0; virtual Archive & operator & (double & d) = 0;
virtual Archive & operator & (int & i) = 0; virtual Archive & operator & (int & i) = 0;
@ -900,6 +903,7 @@ namespace ngcore
private: private:
pybind11::list lst; pybind11::list lst;
size_t index = 0; size_t index = 0;
std::map<std::string, VersionInfo> version_needed;
protected: protected:
using ARCHIVE::stream; using ARCHIVE::stream;
using ARCHIVE::version_map; using ARCHIVE::version_map;
@ -915,9 +919,26 @@ namespace ngcore
{ {
stream = std::make_shared<std::stringstream> stream = std::make_shared<std::stringstream>
(pybind11::cast<pybind11::bytes>(lst[pybind11::len(lst)-1])); (pybind11::cast<pybind11::bytes>(lst[pybind11::len(lst)-1]));
*this & version_map; *this & version_needed;
logger->debug("versions needed for unpickling = {}", version_needed);
for(auto& libversion : version_needed)
if(libversion.second > GetLibraryVersion(libversion.first))
throw Exception("Error in unpickling data:\nLibrary " + libversion.first +
" must be at least " + libversion.second.to_string());
stream = std::make_shared<std::stringstream> stream = std::make_shared<std::stringstream>
(pybind11::cast<pybind11::bytes>(lst[pybind11::len(lst)-2])); (pybind11::cast<pybind11::bytes>(lst[pybind11::len(lst)-2]));
*this & version_map;
stream = std::make_shared<std::stringstream>
(pybind11::cast<pybind11::bytes>(lst[pybind11::len(lst)-3]));
}
}
void NeedsVersion(const std::string& library, const std::string& version) override
{
if(Output())
{
logger->debug("Need version {} of library {}.", version, library);
version_needed[library] = version_needed[library] > version ? version_needed[library] : version;
} }
} }
@ -936,6 +957,12 @@ namespace ngcore
lst.append(pybind11::bytes(std::static_pointer_cast<std::stringstream>(stream)->str())); lst.append(pybind11::bytes(std::static_pointer_cast<std::stringstream>(stream)->str()));
stream = std::make_shared<std::stringstream>(); stream = std::make_shared<std::stringstream>();
*this & GetLibraryVersions(); *this & GetLibraryVersions();
FlushBuffer();
lst.append(pybind11::bytes(std::static_pointer_cast<std::stringstream>(stream)->str()));
stream = std::make_shared<std::stringstream>();
logger->debug("Writeout version needed = {}", version_needed);
*this & version_needed;
FlushBuffer();
lst.append(pybind11::bytes(std::static_pointer_cast<std::stringstream>(stream)->str())); lst.append(pybind11::bytes(std::static_pointer_cast<std::stringstream>(stream)->str()));
return lst; return lst;
} }
@ -949,17 +976,17 @@ namespace ngcore
PyArchive<T_ARCHIVE_OUT> ar; PyArchive<T_ARCHIVE_OUT> ar;
ar & self; ar & self;
auto output = pybind11::make_tuple(ar.WriteOut()); auto output = pybind11::make_tuple(ar.WriteOut());
NETGEN_DEBUG_LOG(GetLogger("Archive"), "pickling output for object of type " + GetLogger("Archive")->trace("Pickling output for object of type {} = {}",
Demangle(typeid(T).name()) + " = " + Demangle(typeid(T).name()),
std::string(pybind11::str(output))); std::string(pybind11::str(output)));
return output; return output;
}, },
[](pybind11::tuple state) [](pybind11::tuple state)
{ {
T* val = nullptr; T* val = nullptr;
NETGEN_DEBUG_LOG(GetLogger("Archive"), "State for unpickling of object of type " + GetLogger("Archive")->trace("State for unpickling of object of type {} = {}",
Demangle(typeid(T).name()) + " = " + Demangle(typeid(T).name()),
std::string(pybind11::str(state[0]))); std::string(pybind11::str(state[0])));
PyArchive<T_ARCHIVE_IN> ar(state[0]); PyArchive<T_ARCHIVE_IN> ar(state[0]);
ar & val; ar & val;
return val; return val;

View File

@ -2,6 +2,8 @@
#define NETGEN_CORE_UTILS_HPP #define NETGEN_CORE_UTILS_HPP
#include <chrono> #include <chrono>
#include <map>
#include <ostream>
#include <sstream> #include <sstream>
#include <string> #include <string>
@ -56,7 +58,13 @@ namespace ngcore
return ss.str(); return ss.str();
} }
template<typename T1, typename T2>
std::ostream& operator << (std::ostream& ost, const std::map<T1,T2>& map)
{
for(auto& val : map)
ost << "\n" << val.first << ": " << val.second;
return ost;
}
} // namespace ngcore } // namespace ngcore
#endif // NETGEN_CORE_UTILS_HPP #endif // NETGEN_CORE_UTILS_HPP

View File

@ -1,6 +1,7 @@
#ifndef NETGEN_CORE_VERSION_HPP #ifndef NETGEN_CORE_VERSION_HPP
#define NETGEN_CORE_VERSION_HPP #define NETGEN_CORE_VERSION_HPP
#include <ostream>
#include <string> #include <string>
#include <tuple> #include <tuple>
@ -83,6 +84,11 @@ namespace ngcore
bool operator <=(const VersionInfo& other) const { return !((*this) > other); } bool operator <=(const VersionInfo& other) const { return !((*this) > other); }
bool operator >=(const VersionInfo& other) const { return !((*this) < other); } bool operator >=(const VersionInfo& other) const { return !((*this) < other); }
}; };
inline std::ostream& operator << (std::ostream& ost, const VersionInfo& version)
{
return ost << version.to_string();
}
} // namespace ngcore } // namespace ngcore
#endif // NETGEN_CORE_VERSION_HPP #endif // NETGEN_CORE_VERSION_HPP

View File

@ -236,6 +236,18 @@ void testMultipleInheritance(Archive& in, Archive& out)
} }
} }
void testMap(Archive& in, Archive& out)
{
map<string, VersionInfo> map1;
map1["netgen"] = "v6.2.1901";
out & map1;
out.FlushBuffer();
map<string, VersionInfo> map2;
in & map2;
CHECK(map2.size() == 1);
CHECK(map2["netgen"] == "v6.2.1901");
}
void testArchive(Archive& in, Archive& out) void testArchive(Archive& in, Archive& out)
{ {
SECTION("Empty String") SECTION("Empty String")
@ -285,11 +297,14 @@ void testArchive(Archive& in, Archive& out)
{ {
testNullPtr(in, out); testNullPtr(in, out);
} }
SECTION("map")
{
testMap(in, out);
}
} }
TEST_CASE("BinaryArchive") TEST_CASE("BinaryArchive")
{ {
SetLibraryVersion("netgen","v6.2.1811");
auto stream = make_shared<stringstream>(); auto stream = make_shared<stringstream>();
BinaryOutArchive out(stream); BinaryOutArchive out(stream);
BinaryInArchive in(stream); BinaryInArchive in(stream);
@ -298,7 +313,6 @@ TEST_CASE("BinaryArchive")
TEST_CASE("TextArchive") TEST_CASE("TextArchive")
{ {
SetLibraryVersion("netgen","v6.2.1811");
auto stream = make_shared<stringstream>(); auto stream = make_shared<stringstream>();
TextOutArchive out(stream); TextOutArchive out(stream);
TextInArchive in(stream); TextInArchive in(stream);