GitLab maintenance scheduled for Tomorrow, 2019-09-24, from 12:00 to 13:00 CT - Services will be unavailable during this time.

Commit 08bad35b authored by Matthieu Dorier's avatar Matthieu Dorier

added support for path-like dataset access

parent 04c4bcbf
......@@ -193,7 +193,7 @@ class DataSet : public KeyValueContainer {
/**
* @brief Creates a dataset with a given name inside the
* DataSet. This name must not have the '/' and '#' characters.
* DataSet. This name must not have the '/' and '%' characters.
* A DataSet object pointing to the created dataset is returned.
* If a dataset with this name already exists in the DataStore,
* it is not created, but a DataSet object pointing to the
......@@ -234,28 +234,28 @@ class DataSet : public KeyValueContainer {
DataSet operator[](const std::string& datasetName) const;
/**
* @brief Searches this DataSet for an DataSet with
* the provided name and returns an iterator to it if found,
* @brief Searches this DataSet for a DataSet with
* the provided path and returns an iterator to it if found,
* otherwise it returns an iterator to DataStore::end().
*
* @param datasetName Name of the DataSet to find.
* @param datasetPath Path of the DataSet to find.
*
* @return an iterator pointing to the DataSet if found,
* DataSet::end() otherwise.
*/
iterator find(const std::string& datasetName);
iterator find(const std::string& datasetPath);
/**
* @brief Searches this DataSet for an DataSet with
* the provided name and returns a const_iterator to it
* the provided path and returns a const_iterator to it
* if found, otherwise it returns an iterator to DataSet::end().
*
* @param datasetName Name of the DataSet to find.
* @param datasetPath Path of the DataSet to find.
*
* @return a const_iterator pointing to the DataSet if found,
* DataSet::cend() otherwise.
*/
const_iterator find(const std::string& datasetName) const;
const_iterator find(const std::string& datasetPath) const;
/**
......
......@@ -109,27 +109,27 @@ class DataStore {
/**
* @brief Searches the DataStore for an DataSet with
* the provided name and returns an iterator to it if found,
* the provided path and returns an iterator to it if found,
* otherwise it returns an iterator to DataStore::end().
*
* @param datasetName Name of the DataSet to find.
* @param datasetPath Path of the DataSet to find.
*
* @return an iterator pointing to the DataSet if found,
* DataStore::end() otherwise.
*/
iterator find(const std::string& datasetName);
iterator find(const std::string& datasetPath);
/**
* @brief Searches the DataStore for an DataSet with
* the provided name and returns a const_iterator to it
* the provided path and returns a const_iterator to it
* if found, otherwise it returns an iterator to DataStore::end().
*
* @param datasetName Name of the DataSet to find.
* @param datasetPath Path of the DataSet to find.
*
* @return a const_iterator pointing to the DataSet if found,
* DataStore::cend() otherwise.
*/
const_iterator find(const std::string& datasetName) const;
const_iterator find(const std::string& datasetPath) const;
/**
* @brief Returns an iterator referring to the first DataSet
......@@ -234,7 +234,7 @@ class DataStore {
/**
* @brief Creates a dataset with a given name inside the
* DataStore. This name must not have the '/' and '#' characters.
* DataStore. This name must not have the '/' and '%' characters.
* A DataSet object pointing to the created dataset is returned.
* If a dataset with this name already exists in the DataStore,
* it is not created, but a DataSet object pointing to the
......
......@@ -149,19 +149,35 @@ Run DataSet::operator[](const RunNumber& runNumber) const {
return std::move(*it);
}
DataSet::iterator DataSet::find(const std::string& datasetName) {
DataSet::iterator DataSet::find(const std::string& datasetPath) {
int ret;
if(datasetName.find('/') != std::string::npos
|| datasetName.find('%') != std::string::npos) {
throw Exception("Invalid character '/' or '%' in dataset name");
if(datasetPath.find('%') != std::string::npos) {
throw Exception("Invalid character '%' in dataset name");
}
std::vector<char> data;
size_t slash_count = std::count(datasetPath.begin(), datasetPath.end(), '/');
size_t level = m_impl->m_level + 1 + slash_count;
std::string containerName;
std::string datasetName;
std::string parent = fullname();
bool b = m_impl->m_datastore->m_impl->load(m_impl->m_level+1, parent, datasetName, data);
if(slash_count == 0) {
datasetName = datasetPath;
containerName = parent;
} else {
size_t c = datasetPath.find_last_of('/');
containerName = parent + "/" + datasetPath.substr(0,c);
datasetName = datasetPath.substr(c+1);
}
std::vector<char> data;
bool b = m_impl->m_datastore->m_impl->load(level, containerName, datasetName, data);
if(!b) {
return m_impl->m_datastore->end();
}
return iterator(DataSet(m_impl->m_datastore, m_impl->m_level+1, parent, datasetName));
return iterator(DataSet(m_impl->m_datastore, level, containerName, datasetName));
}
DataSet::const_iterator DataSet::find(const std::string& datasetName) const {
......
......@@ -52,18 +52,33 @@ DataStore::~DataStore() {
}
}
DataStore::iterator DataStore::find(const std::string& datasetName) {
DataStore::iterator DataStore::find(const std::string& datasetPath) {
int ret;
if(datasetName.find('/') != std::string::npos
|| datasetName.find('%') != std::string::npos) {
throw Exception("Invalid character ('/' or '%') in dataset name");
if(datasetPath.find('%') != std::string::npos) {
throw Exception("Invalid character ('%') in dataset name");
}
size_t slash_count = std::count(datasetPath.begin(), datasetPath.end(), '/');
size_t level = 1 + slash_count;
std::string containerName;
std::string datasetName;
if(slash_count == 0) {
datasetName = datasetPath;
containerName = "";
} else {
size_t c = datasetPath.find_last_of('/');
containerName = datasetPath.substr(0,c);
datasetName = datasetPath.substr(c+1);
}
std::vector<char> data;
bool b = m_impl->load(1, "", datasetName, data);
bool b = m_impl->load(level, containerName, datasetName, data);
if(!b) {
return m_impl->m_end;
}
return iterator(DataSet(this, 1, "", datasetName));
return iterator(DataSet(this, level, containerName, datasetName));
}
DataSet DataStore::operator[](const std::string& datasetName) const {
......
......@@ -257,7 +257,7 @@ class DataStore::Impl {
uint64_t h = std::hash<std::string>()(containerName);
ch_placement_find_closest(m_chi_sdskv, h, 1, &provider_idx);
} else {
// use the complete name for final objects (level 255)
// use the complete name for final objects (level 0)
uint64_t h = std::hash<std::string>()(ss.str());
ch_placement_find_closest(m_chi_sdskv, h, 1, &provider_idx);
}
......
......@@ -32,6 +32,17 @@ void DataSetTest::testFillDataStore() {
CPPUNIT_ASSERT_EQUAL_STR("ds1", ds1.name());
CPPUNIT_ASSERT_EQUAL_STR("matthieu", ds1.container());
CPPUNIT_ASSERT_EQUAL_STR("matthieu/ds1", ds1.fullname());
// assert access from DataStore using full path
DataSet matthieu_ds1 = (*datastore)["matthieu/ds1"];
CPPUNIT_ASSERT(matthieu_ds1.valid());
CPPUNIT_ASSERT(matthieu_ds1 == ds1);
// create a dataset inside ds1
DataSet ds11 = ds1.createDataSet("ds11");
CPPUNIT_ASSERT(ds11.valid());
// access ds11 using path from "matthieu"
DataSet ds1_ds11 = mds["ds1/ds11"];
CPPUNIT_ASSERT(ds1_ds11.valid());
CPPUNIT_ASSERT(ds1_ds11 == ds11);
// assert comparison with a default-constructed dataset
DataSet ds0;
CPPUNIT_ASSERT(ds0 != ds1);
......
#include <sstream>
#include <iostream>
#include <boost/serialization/vector.hpp>
#include <hepnos.hpp>
class InputTag {
private:
template<typename S>
friend S& operator<<(S&, const InputTag&);
std::string _a;
std::string _b;
public:
InputTag(const std::string& a, const std::string& b)
: _a(a), _b(b) {}
};
template<typename S>
S& operator<<(S& ss, const InputTag& t) {
ss << t._a << "_" << t._b;
return ss;
}
class Particle {
private:
friend class boost::serialization::access;
std::vector<double> position;
uint8_t charge;
/* any serializable class needs to have this function.
Note that if your class has members that are STL containers
(e.g. std::vector<X>) then you will need to #include
the corresponding Boost header (e.g. boot/serialization/vector.hpp).
For more information about the serialization mechanism,
see here: http://www.boost.org/doc/libs/1_66_0/libs/serialization/doc/index.html
*/
template<typename A>
void serialize(A& ar, const unsigned int version) {
ar & position;
ar & charge;
}
public:
Particle() = default;
Particle(double x, double y, double z, uint8_t c)
: position{x,y,z}, charge(c) {}
bool operator==(const Particle& other) {
if(charge != other.charge) return false;
if(position.size() != other.position.size()) return false;
for(unsigned i=0; i<position.size(); i++) {
if(position[i] != other.position[i]) return false;
}
return true;
}
};
using namespace hepnos;
int main(int argc, char** argv) {
if(argc != 2) {
std::cerr << "Usage: " << argv[1] << " <configfile>" << std::endl;
exit(-1);
}
DataStore datastore(argv[1]);
DataSet ds = datastore.createDataSet("fermilab");
InputTag tag("AAA","BBB");
Particle p_in(3.4, 5.6, 7.8, 42);
Particle p_out;
std::cout << "p_in == p_out ? " << (p_in == p_out) << std::endl;
ds.store(tag, p_in);
ds.load(tag, p_out);
std::cout << "p_in == p_out ? " << (p_in == p_out) << std::endl;
datastore.shutdown();
return 0;
}
#if 0
#include <iostream>
#include <hepnos/DataStore.hpp>
#include <hepnos/DataSet.hpp>
......@@ -80,7 +165,7 @@ int main(int argc, char** argv) {
std::cout << "created run with run number " << run43.number() << std::endl;
std::cout << "created run with run number " << run23.number() << std::endl;
std::cout << "created run with run number " << run56.number() << std::endl;
std::cout << "====== Testing runs().begin() and runs().end() =====" << std::endl;
for(auto& r : dataset4.runs()) {
std::cout << "accessing a run with number " << r.number() << std::endl;
......@@ -107,3 +192,4 @@ int main(int argc, char** argv) {
return 0;
}
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment