Commit 5c651736 authored by Matthieu Dorier's avatar Matthieu Dorier

big refactoring to use better pimpl idiom based on shared ptr

parent 18f93fd1
......@@ -36,7 +36,7 @@ int main(int argc, char* argv[])
exit(-1);
}
hepnos::DataStore datastore(argv[1]);
hepnos::DataStore datastore = hepnos::DataStore::connect(argv[1]);
for(auto& ds : datastore) {
navigate_dataset(0, ds);
}
......
......@@ -8,7 +8,7 @@ int main(int argc, char* argv[])
exit(-1);
}
hepnos::DataStore datastore(argv[1]);
hepnos::DataStore datastore = hepnos::DataStore::connect(argv[1]);
datastore.shutdown();
return 0;
......
......@@ -32,31 +32,17 @@ class DataSet : public KeyValueContainer {
private:
/**
* @brief Constructor.
*
* @param ds DataStore to which this DataSet belongs.
* @param level Level of nesting.
* @param fullname Full name of the DataSet.
*/
DataSet(DataStore* ds, uint8_t level, const std::string& fullname);
/**
* @brief Constructor.
*
* @param ds DataStore to which this DataSet belongs.
* @param level Level of nesting.
* @param container Full name of the parent DataSet ("" if no parent).
* @param name Name of the DataSet.
* @brief Implementation class (used for the Pimpl idiom).
*/
DataSet(DataStore* ds, uint8_t level, const std::shared_ptr<std::string>& container, const std::string& name);
class Impl;
std::shared_ptr<Impl> m_impl; /*!< Pointer to implementation. */
/**
* @brief Implementation class (used for the Pimpl idiom).
* @brief Constructor.
*/
class Impl;
std::unique_ptr<Impl> m_impl; /*!< Pointer to implementation. */
DataSet(const std::shared_ptr<Impl>& impl);
DataSet(std::shared_ptr<Impl>&& impl);
public:
......@@ -72,14 +58,14 @@ class DataSet : public KeyValueContainer {
*
* @param other DataSet to copy.
*/
DataSet(const DataSet& other);
DataSet(const DataSet& other) = default;
/**
* @brief Move-constructor.
*
* @param other DataSet to move.
*/
DataSet(DataSet&& other);
DataSet(DataSet&& other) = default;
/**
* @brief Copy-assignment operator.
......@@ -88,7 +74,7 @@ class DataSet : public KeyValueContainer {
*
* @return this.
*/
DataSet& operator=(const DataSet& other);
DataSet& operator=(const DataSet& other) = default;
/**
* @brief Move-assignment operator.
......@@ -97,17 +83,17 @@ class DataSet : public KeyValueContainer {
*
* @return this.
*/
DataSet& operator=(DataSet&& other);
DataSet& operator=(DataSet&& other) = default;
/**
* @brief Destructor.
*/
~DataSet();
~DataSet() = default;
/**
* @brief Overrides getDataStore from KeyValueContainer class.
* @brief Overrides datastore from KeyValueContainer class.
*/
DataStore* getDataStore() const override;
DataStore datastore() const override;
/**
* @brief Name of the DataSet.
......@@ -369,18 +355,11 @@ class DataSet : public KeyValueContainer {
const_iterator upper_bound(const std::string& ub) const;
/**
* @brief Returns a reference to the RunSet associated with this DataSet.
*
* @return a reference to the RunSet associated with this DataSet.
*/
RunSet& runs();
/**
* @brief Returns a reference to the RunSet associated with this DataSet.
* @brief Returns the RunSet associated with this DataSet.
*
* @return a reference to the RunSet associated with this DataSet.
*/
const RunSet& runs() const;
RunSet runs() const;
/**
* @brief Accesses an existing run using the []
......
......@@ -44,7 +44,7 @@ class DataStore {
* the name of the configuration file from the environment
* variable HEPNOS_CONFIG_FILE.
*/
DataStore();
static DataStore connect();
/**
* @brief Constructor. Initializes the DataStore using a YAML
......@@ -53,24 +53,29 @@ class DataStore {
*
* @param configFile Path to a YAML configuration file.
*/
DataStore(const std::string& configFile);
static DataStore connect(const std::string& configFile);
/**
* @brief Copy constructor is deleted.
* @brief Default constructor (for an invalid DataStore not yet initialized).
*/
DataStore(const DataStore&) = delete;
DataStore() = default;
/**
* @brief Copy constructor.
*/
DataStore(const DataStore&) = default;
/**
* @brief Move constructor.
*
* @param other DataStore to move from.
*/
DataStore(DataStore&& other);
DataStore(DataStore&& other) = default;
/**
* @brief Copy-assignment operator. Deleted.
* @brief Copy-assignment operator.
*/
DataStore& operator=(const DataStore&) = delete;
DataStore& operator=(const DataStore&) = default;
/**
* @brief Move-assignment operator.
......@@ -79,12 +84,17 @@ class DataStore {
*
* @return This DataStore.
*/
DataStore& operator=(DataStore&& other);
DataStore& operator=(DataStore&& other) = default;
/**
* @brief Destructor.
*/
~DataStore();
~DataStore() = default;
/**
* @brief Indicated whether the DataStore is valid (i.e. connected).
*/
bool valid() const;
/**
* @brief Accesses an existing DataSet using the []
......@@ -325,7 +335,15 @@ class DataStore {
* @brief Implementation of the class (using Pimpl idiom)
*/
class Impl;
std::unique_ptr<Impl> m_impl; /*!< Pointer to implementation */
std::shared_ptr<Impl> m_impl; /*!< Pointer to implementation */
/**
* @brief Constructor from a pointer to implementation.
*
* @param impl
*/
DataStore(std::shared_ptr<Impl>&& impl);
DataStore(const std::shared_ptr<Impl>& impl);
/**
* @brief Loads the raw data corresponding to a product.
......@@ -637,12 +655,12 @@ namespace hepnos {
template<typename T>
Ptr<T> DataStore::makePtr(const ProductID& productID) {
return Ptr<T>(this, productID);
return Ptr<T>(*this, productID);
}
template<typename T, typename C = std::vector<T>>
Ptr<T,C> DataStore::makePtr(const ProductID& productID, std::size_t index) {
return Ptr<T,C>(this, productID, index);
return Ptr<T,C>(*this, productID, index);
}
template<typename T>
......@@ -662,7 +680,7 @@ bool DataStore::loadProductImpl(const ProductID& productID, T& t, const std::int
return false;
}
std::stringstream ss(buffer);
InputArchive ia(this, ss);
InputArchive ia(*this, ss);
try {
ia >> t;
} catch(...) {
......@@ -688,7 +706,7 @@ bool DataStore::loadProductImpl(const ProductID& productID, std::vector<T>& t, c
return false;
}
std::stringstream ss(buffer);
InputArchive ia(this, ss);
InputArchive ia(*this, ss);
try {
size_t count = 0;
ia >> count;
......
......@@ -22,17 +22,13 @@ class Event : public KeyValueContainer {
friend class SubRun;
class Impl;
std::unique_ptr<Impl> m_impl;
std::shared_ptr<Impl> m_impl;
/**
* @brief Constructor.
*
* @param datastore Pointer to the DataStore managing the underlying data.
* @param level Level of nesting.
* @param container Full name of the container containing the event.
* @param n Event number.
*/
Event(DataStore* datastore, uint8_t level, const std::shared_ptr<std::string>& container, const EventNumber& n);
Event(std::shared_ptr<Impl>&& impl);
Event(const std::shared_ptr<Impl>& impl);
public:
......@@ -46,14 +42,14 @@ class Event : public KeyValueContainer {
*
* @param other Event to copy.
*/
Event(const Event& other);
Event(const Event& other) = default;
/**
* @brief Move constructor.
*
* @param other Event to move.
*/
Event(Event&& other);
Event(Event&& other) = default;
/**
* @brief Copy-assignment operator.
......@@ -62,7 +58,7 @@ class Event : public KeyValueContainer {
*
* @return Reference to this Run.
*/
Event& operator=(const Event& other);
Event& operator=(const Event& other) = default;
/**
* @brief Move-assignment operator.
......@@ -71,17 +67,17 @@ class Event : public KeyValueContainer {
*
* @return Reference to this Run.
*/
Event& operator=(Event&& other);
Event& operator=(Event&& other) = default;
/**
* @brief Destructor.
*/
~Event();
~Event() = default;
/**
* @brief Overrides getDataStore from KeyValueContainer class.
* @brief Overrides datastore() from KeyValueContainer class.
*/
DataStore* getDataStore() const override;
DataStore datastore() const override;
/**
* @brief Returns the next Event in the same container,
......
......@@ -30,16 +30,21 @@ class InputArchive : public iarchive {
private:
DataStore* m_datastore = nullptr;
DataStore m_datastore;
public:
template<typename ... Args>
InputArchive(DataStore* datastore, Args&& ... args)
InputArchive(DataStore&& datastore, Args&& ... args)
: iarchive(std::forward<Args>(args)..., boost::archive::archive_flags::no_header)
, m_datastore(std::move(datastore)) {}
template<typename ... Args>
InputArchive(const DataStore& datastore, Args&& ... args)
: iarchive(std::forward<Args>(args)..., boost::archive::archive_flags::no_header)
, m_datastore(datastore) {}
DataStore* getDataStore() const {
DataStore datastore() const {
return m_datastore;
}
......
......@@ -16,6 +16,7 @@
#include <hepnos/ProductID.hpp>
#include <hepnos/Demangle.hpp>
#include <hepnos/Exception.hpp>
#include <hepnos/DataStore.hpp>
namespace hepnos {
......@@ -60,7 +61,7 @@ class KeyValueContainer {
*
* @return DataStore.
*/
virtual DataStore* getDataStore() const = 0;
virtual DataStore datastore() const = 0;
/**
* @brief Stores raw key/value data in this KeyValueContainer.
......@@ -268,7 +269,7 @@ class KeyValueContainer {
}
try {
std::stringstream ss(buffer);
InputArchive ia(getDataStore(), ss);
InputArchive ia(datastore(), ss);
ia >> value;
} catch(...) {
throw Exception("Exception occured during serialization");
......@@ -315,7 +316,7 @@ class KeyValueContainer {
}
try {
std::stringstream ss(buffer);
InputArchive ia(getDataStore(), ss);
InputArchive ia(datastore(), ss);
size_t count = 0;
ia >> count;
value.resize(count);
......
......@@ -30,7 +30,7 @@ class Ptr {
private:
DataStore* m_datastore = nullptr;
DataStore m_datastore;
ProductID m_product_id = ProductID();
std::size_t m_index = 0;
bool m_is_in_container = false;
......@@ -38,14 +38,14 @@ class Ptr {
T* m_data = nullptr;
size_t* m_refcount = nullptr;
Ptr(DataStore* datastore, const ProductID& product_id)
Ptr(const DataStore& datastore, const ProductID& product_id)
: m_datastore(datastore)
, m_product_id(product_id)
, m_index(0)
, m_is_in_container(false)
, m_refcount(new size_t(1)) {}
Ptr(DataStore* datastore, const ProductID& product_id, std::size_t index)
Ptr(const DataStore& datastore, const ProductID& product_id, std::size_t index)
: m_datastore(datastore)
, m_product_id(product_id)
, m_index(index)
......@@ -136,7 +136,6 @@ class Ptr {
m_is_in_container = other.m_is_in_container;
m_container = other.m_container;
m_refcount = other.m_refcount;
other.m_datastore = nullptr;
other.m_index = 0;
other.m_container = nullptr;
other.m_refcount = nullptr;
......@@ -165,7 +164,6 @@ class Ptr {
}
}
}
m_datastore = nullptr;
m_product_id = ProductID();
m_index = 0;
m_is_in_container = false;
......@@ -182,7 +180,7 @@ class Ptr {
* underlying service, false otherwise.
*/
bool valid() const {
return m_datastore != nullptr && m_product_id.valid();
return m_datastore.valid() && m_product_id.valid();
}
/**
......@@ -268,7 +266,7 @@ class Ptr {
*/
template<typename Archive>
void load(Archive& ar, const unsigned int version) {
m_datastore = ar.getDataStore();
m_datastore = ar.datastore();
ar & m_product_id;
ar & m_is_in_container;
if(m_is_in_container) {
......@@ -284,14 +282,14 @@ class Ptr {
void loadData() {
if(m_is_in_container) {
m_container = new C();
if(!(m_datastore->loadProduct(m_product_id, *m_container))) {
if(!(m_datastore.loadProduct(m_product_id, *m_container))) {
throw Exception("Could not load product from DataStore");
}
m_data = &((*m_container)[m_index]);
} else {
m_data = new T();
m_container = nullptr;
if(!(m_datastore->loadProduct(m_product_id, *m_data))) {
if(!(m_datastore.loadProduct(m_product_id, *m_data))) {
throw Exception("Could not load product from DataStore");
}
}
......
......@@ -26,18 +26,13 @@ class Run : public KeyValueContainer {
friend class DataSet;
class Impl;
std::unique_ptr<Impl> m_impl;
std::shared_ptr<Impl> m_impl;
/**
* @brief Constructor.
*
* @param datastore Pointer to the DataStore managing the underlying data.
* @param level Level of nesting.
* @param container Full name of the dataset containing the run.
* @param run Run number.
*/
Run(DataStore* datastore, uint8_t level,
const std::shared_ptr<std::string>& container, const RunNumber& run);
Run(const std::shared_ptr<Impl>& impl);
Run(std::shared_ptr<Impl>&& impl);
public:
......@@ -53,14 +48,14 @@ class Run : public KeyValueContainer {
*
* @param other Run to copy.
*/
Run(const Run& other);
Run(const Run& other) = default;
/**
* @brief Move constructor.
*
* @param other Run to move.
*/
Run(Run&& other);
Run(Run&& other) = default;
/**
* @brief Copy-assignment operator.
......@@ -69,7 +64,7 @@ class Run : public KeyValueContainer {
*
* @return Reference to this Run.
*/
Run& operator=(const Run& other);
Run& operator=(const Run& other) = default;
/**
* @brief Move-assignment operator.
......@@ -78,17 +73,17 @@ class Run : public KeyValueContainer {
*
* @return Reference to this Run.
*/
Run& operator=(Run&& other);
Run& operator=(Run&& other) = default;
/**
* @brief Destructor.
*/
~Run();
~Run() = default;
/**
* @brief Overrides getDataStore from KeyValueContainer class.
* @brief Overrides datastore from KeyValueContainer class.
*/
DataStore* getDataStore() const override;
DataStore datastore() const override;
/**
* @brief Returns the next Run in the same container,
......
......@@ -21,51 +21,49 @@ namespace hepnos {
*/
class RunSet {
friend class DataSet::Impl;
friend class DataSet;
private:
/**
* @brief Constructor.
*
* @param ds DataSet to which this RunSet belongs.
* @brief Implementation class (used for the Pimpl idiom).
*/
RunSet(DataSet* ds);
using Impl = DataSet::Impl;
std::shared_ptr<Impl> m_impl; /*!< Pointer to implementation. */
/**
* @brief Implementation class (used for the Pimpl idiom).
* @brief Constructor.
*/
class Impl;
std::unique_ptr<Impl> m_impl; /*!< Pointer to implementation. */
RunSet(const std::shared_ptr<Impl>& impl);
RunSet(std::shared_ptr<Impl>&& impl);
public:
typedef Run value_type;
/**
* @brief Copy-constructor. Deleted.
* @brief Copy-constructor.
*
* @param other RunSet to copy.
*/
RunSet(const RunSet& other) = delete;
RunSet(const RunSet& other) = default;
/**
* @brief Move-constructor. Deleted.
*
* @param other RunSet to move.
*/
RunSet(RunSet&& other) = delete;
RunSet(RunSet&& other) = default;
/**
* @brief Copy-assignment operator. Deleted.
* @brief Copy-assignment operator.
*
* @param other RunSet to copy.
*
* @return this.
*/
RunSet& operator=(const RunSet& other) = delete;
RunSet& operator=(const RunSet& other) = default;
/**
* @brief Move-assignment operator. Deleted.
......@@ -74,16 +72,21 @@ class RunSet {
*
* @return this.
*/
RunSet& operator=(RunSet&& other) = delete;
RunSet& operator=(RunSet&& other) = default;
/**
* @brief Destructor.
*/
~RunSet();
~RunSet() = default;
class const_iterator;
class iterator;
/**
* @brief Get the DataStore to which this RunSet belongs.
*/
DataStore datastore() const;
/**
* @brief Accesses an existing Run using the []
* operator. If no Run correspond to the provided number,
......
......@@ -23,17 +23,13 @@ class SubRun : public KeyValueContainer {
friend class Run;
class Impl;
std::unique_ptr<Impl> m_impl;
std::shared_ptr<Impl> m_impl;
/**
* @brief Constructor.
*
* @param datastore Pointer to the DataStore managing the underlying data.
* @param level Level of nesting.
* @param container Full name of the dataset containing the run.
* @param run SubRun number.
*/
SubRun(DataStore* datastore, uint8_t level, const std::shared_ptr<std::string>& container, const SubRunNumber& run);
SubRun(std::shared_ptr<Impl>&& impl);
SubRun(const std::shared_ptr<Impl>& impl);
public:
......@@ -49,14 +45,14 @@ class SubRun : public KeyValueContainer {
*
* @param other SubRun to copy.
*/
SubRun(const SubRun& other);
SubRun(const SubRun& other) = default;
/**
* @brief Move constructor.
*
* @param other SubRun to move.
*/
SubRun(SubRun&& other);
SubRun(SubRun&& other) = default;
/**
* @brief Copy-assignment operator.
......@@ -65,7 +61,7 @@ class SubRun : public KeyValueContainer {
*
* @return Reference to this Run.
*/
SubRun& operator=(const SubRun& other);
SubRun& operator=(const SubRun& other) = default;
/**
* @brief Move-assignment operator.
......@@ -74,17 +70,17 @@ class SubRun : public KeyValueContainer {
*
* @return Reference to this Run.
*/
SubRun& operator=(SubRun&& other);
SubRun& operator=(SubRun&& other) = default;
/**
* @brief Destructor.
*/
~SubRun();
~SubRun() = default;
/**
* @brief Overrides getDataStore from KeyValueContainer class.
* @brief Overrides datastore from KeyValueContainer class.
*/
DataStore* getDataStore() const override;
DataStore datastore() const override;
/**
* @brief Returns the next SubRun in the same container,
......
This diff is collapsed.
......@@ -6,7 +6,9 @@
#ifndef __HEPNOS_PRIVATE_DATASET_IMPL_H
#define __HEPNOS_PRIVATE_DATASET_IMPL_H
#include "DataStoreImpl.hpp"
#include "hepnos/DataSet.hpp"
#include "hepnos/RunSet.hpp"
namespace hepnos {
......@@ -14,19 +16,41 @@ class DataSet::Impl {
public:
DataStore* m_datastore;
uint8_t m_level;
std::shared_ptr<std::string> m_container;
std::string m_name;
RunSet m_runset;
std::shared_ptr<DataStore::Impl> m_datastore;
uint8_t m_level;
std::shared_ptr<std::string> m_container;
std::string m_name;
Impl(DataSet* dataset, DataStore* ds, uint8_t level,
const std::shared_ptr<std::string>& container, const std::string& name)
Impl(const std::shared_ptr<DataStore::Impl>& ds,
uint8_t level,
const std::shared_ptr<std::string>& container,
const std::string& name)
: m_datastore(ds)
, m_level(level)
, m_container(container)
, m_name(name)
, m_runset(dataset) {}
, m_name(name) {}
Impl(const std::shared_ptr<DataStore::Impl>& ds,
uint8_t level,
const std::string& fullname)
: m_datastore(ds)
, m_level(level) {
size_t p = fullname.find_last_of('/');
if(p == std::string::npos) {
m_name = fullname;
m_container = std::make_shared<std::string>("");
} else {
m_name = fullname.substr(p+1);
m_container = std::make_shared<std::string>(fullname.substr(0, p));
}
}
std::string fullname() const {
if(m_container->size() > 0)
return *m_container + "/" + m_name;
else
return m_name;
}
};
}
......