/* * (C) 2018 The University of Chicago * * See COPYRIGHT in top-level directory. */ #ifndef __HEPNOS_KEYVAL_CONTAINER_H #define __HEPNOS_KEYVAL_CONTAINER_H #include #include #include #include #include #include #include #include #include namespace hepnos { class KeyValueContainer { public: /** * @brief Default constructor. */ KeyValueContainer() = default; /** * @brief Copy constructor. */ KeyValueContainer(const KeyValueContainer& other) = default; /** * @brief Move constructor. */ KeyValueContainer(KeyValueContainer&& other) = default; /** * @brief Copy-assignment operator. */ KeyValueContainer& operator=(const KeyValueContainer& other) = default; /** * @brief Move-assignment operator. */ KeyValueContainer& operator=(KeyValueContainer&& other) = default; /** * @brief Destructor. */ virtual ~KeyValueContainer() = default; /** * @brief Stores raw key/value data in this KeyValueContainer. * This function is virtual and must be overloaded in the child class. * * @param key Key * @param buffer Value * * @return true if the key did not already exist, false otherwise. */ virtual bool storeRawData(const std::string& key, const std::vector& buffer) = 0; /** * @brief Loads raw key/value data from this KeyValueContainer. * This function is virtual and must be overloaded in the child class. * * @param key Key * @param buffer Buffer used to hold the value. * * @return true if the key exists, false otherwise. */ virtual bool loadRawData(const std::string& key, std::vector& buffer) const = 0; /** * @brief Stores a key/value pair into the KeyValueContainer. * The type of the key should have operator<< available * to stream it into a std::stringstream for the purpose * of converting it into an std::string. The resulting * string must not have the "/", or "%" characters. The * type of the value must be serializable using Boost. * * @tparam K type of the key. * @tparam V type of the value. * @param key Key to store. * @param value Value to store. * * @return true if the key was found. false otherwise. */ template bool store(const K& key, const V& value) { std::stringstream ss_value; std::stringstream ss_key; ss_key << key << "#" << demangle(); boost::archive::binary_oarchive oa(ss_value); try { oa << value; } catch(...) { throw Exception("Exception occured during serialization"); } std::string serialized = ss_value.str(); std::vector buffer(serialized.begin(), serialized.end()); return storeRawData(ss_key.str(), buffer); } /** * @brief Loads a value associated with a key from the * KeyValueContainer. The type of the key should have * operator<< available to stream it into a std::stringstream * for the purpose of converting it into an std::string. * The resulting string must not have the "/" or "%" characters. * The type of the value must be serializable using Boost. * * @tparam K type of the key. * @tparam V type of the value. * @param key Key to load. * @param value Value to load. * * @return true if the key exists and was loaded. False otherwise. */ template bool load(const K& key, V& value) const { std::vector buffer; std::stringstream ss_key; ss_key << key << "#" << demangle(); if(!loadRawData(ss_key.str(), buffer)) { return false; } try { std::string serialized(buffer.begin(), buffer.end()); std::stringstream ss(serialized); boost::archive::binary_iarchive ia(ss); ia >> value; } catch(...) { throw Exception("Exception occured during serialization"); } return true; } }; } #endif