diff --git a/src/DataSet.cpp b/src/DataSet.cpp index 800c520968ea9d71f502d6202540665253df7aef..6941fedf78e902f5d958d28bf074459155e2a9ec 100644 --- a/src/DataSet.cpp +++ b/src/DataSet.cpp @@ -179,7 +179,7 @@ Run DataSet::createRun(const RunNumber& runNumber) { throw Exception("Trying to create a Run with InvalidRunNumber"); } std::string parent = fullname(); - std::string runStr = Run::Impl::makeKeyStringFromRunNumber(runNumber); + std::string runStr = makeKeyStringFromNumber(runNumber); m_impl->m_datastore->m_impl->store(m_impl->m_level+1, parent, runStr); return Run(m_impl->m_datastore, m_impl->m_level+1, std::make_shared(parent), runNumber); @@ -190,7 +190,7 @@ Run DataSet::createRun(WriteBatch& batch, const RunNumber& runNumber) { throw Exception("Trying to create a Run with InvalidRunNumber"); } std::string parent = fullname(); - std::string runStr = Run::Impl::makeKeyStringFromRunNumber(runNumber); + std::string runStr = makeKeyStringFromNumber(runNumber); batch.m_impl->store(m_impl->m_level+1, parent, runStr); return Run(m_impl->m_datastore, m_impl->m_level+1, std::make_shared(parent), runNumber); diff --git a/src/Event.cpp b/src/Event.cpp index f67fb905f19f4825b6160ff5c902de985d5247a3..935bd614da8ee03630cd095ba560402216ed743d 100644 --- a/src/Event.cpp +++ b/src/Event.cpp @@ -51,7 +51,7 @@ Event Event::next() const { if(s == 0) return Event(); size_t i = m_impl->m_container->size()+1; if(keys[0].size() <= i) return Event(); - EventNumber n = Impl::parseEventNumberFromKeyString(&keys[0][i]); + EventNumber n = parseNumberFromKeyString(&keys[0][i]); if(n == InvalidEventNumber) return Event(); return Event(m_impl->m_datastore, m_impl->m_level, m_impl->m_container, n); } diff --git a/src/EventImpl.hpp b/src/EventImpl.hpp index 458d254a2d69bda242da3932efac37e6784b9578..3f97ef815218e2fbf5968bd9f7b1e580f00d7c8b 100644 --- a/src/EventImpl.hpp +++ b/src/EventImpl.hpp @@ -11,6 +11,7 @@ #include #include #include "hepnos/Event.hpp" +#include "NumberUtil.hpp" namespace hepnos { @@ -29,52 +30,8 @@ class Event::Impl { , m_container(container) , m_event_nr(n) {} - static std::string makeKeyStringFromEventNumber(const EventNumber& n) { - std::string str(1+sizeof(n),'\0'); - str[0] = '%'; -#ifndef HEPNOS_READABLE_NUMBERS -#if BOOST_ENDIAN_BIG_BYTE - std::memcpy(&str[1], &n, sizeof(n)); - return str; -#else - unsigned i = sizeof(n); - auto n2 = n; - while(n2 != 0) { - str[i] = n2 & 0xff; - n2 = n2 >> 8; - i -= 1; - } - return str; -#endif -#else - std::stringstream strstr; - strstr << "%" << std::setfill('0') << std::setw(16) << std::hex << n; - return strstr.str(); -#endif - } - - static EventNumber parseEventNumberFromKeyString(const char* str) { - if(str[0] != '%') return InvalidEventNumber; - EventNumber n; -#ifdef HEPNOS_READABLE_NUMBERS - std::stringstream strEventNumber; - strEventNumber << std::hex << std::string(str+1, 16); - strEventNumber >> n; -#else -#if BOOST_ENDIAN_BIG_BYTE - std::memcpy(&n, &str[1], sizeof(n)); -#else - n = 0; - for(unsigned i=0; i < sizeof(n); i++) { - n = 256*n + str[i+1]; - } -#endif -#endif - return n; - } - std::string makeKeyStringFromEventNumber() const { - return makeKeyStringFromEventNumber(m_event_nr); + return makeKeyStringFromNumber(m_event_nr); } std::string fullpath() const { diff --git a/src/NumberUtil.hpp b/src/NumberUtil.hpp new file mode 100644 index 0000000000000000000000000000000000000000..9f2142614c02c4b3461d2ffb942ed5ff34d52b35 --- /dev/null +++ b/src/NumberUtil.hpp @@ -0,0 +1,69 @@ +/* + * (C) 2018 The University of Chicago + * + * See COPYRIGHT in top-level directory. + */ +#ifndef __HEPNOS_PRIVATE_NUMBER_UTIL_H +#define __HEPNOS_PRIVATE_NUMBER_UTIL_H + +#include +#include +#include + +namespace hepnos { + +template +static std::string makeReadableKeyStringFromNumber(const T& n) { + constexpr int s = sizeof(T)*2; + std::stringstream strstr; + strstr << '%' << std::setfill('0') << std::setw(s) << std::hex << n; + return strstr.str(); +} + +template +static std::string makeKeyStringFromNumber(const T& n) { +#ifdef HEPNOS_READABLE_NUMBERS + return makeReadableKeyStringFromNumber(n); +#else + std::string str(1+sizeof(n),'\0'); + str[0] = '%'; +#if BOOST_ENDIAN_BIG_BYTE + std::memcpy(&str[1], &n, sizeof(n)); + return str; +#else + unsigned i = sizeof(n); + auto n2 = n; + while(n2 != 0) { + str[i] = n2 & 0xff; + n2 = n2 >> 8; + i -= 1; + } + return str; +#endif +#endif +} + +template +static T parseNumberFromKeyString(const char* str) { + // string is assumed to start with a '%' + T n; +#ifdef HEPNOS_READABLE_NUMBERS + std::stringstream strNumber; + strNumber << std::hex << std::string(str+1, sizeof(T)*2); + strNumber >> n; +#else +#if BOOST_ENDIAN_BIG_BYTE + std::memcpy(&n, &str[1], sizeof(n)); +#else + n = 0; + for(unsigned i=0; i < sizeof(n); i++) { + n = 256*n + str[i+1]; + } +#endif +#endif + return n; +} + +} + +#endif diff --git a/src/Run.cpp b/src/Run.cpp index dbe1f0a775e9b3d23e1767f20ee1a395bd32a563..e9e7df4163c1f7df74545d8ff8e4f67b2214939d 100644 --- a/src/Run.cpp +++ b/src/Run.cpp @@ -11,6 +11,8 @@ namespace hepnos { +Run::iterator Run::Impl::m_end; + Run::Run() : m_impl(std::make_unique(nullptr, 0, std::make_shared(""), InvalidRunNumber)) {} @@ -48,14 +50,15 @@ Run Run::next() const { std::vector keys; size_t s = m_impl->m_datastore->m_impl->nextKeys( - m_impl->m_level, *m_impl->m_container, + m_impl->m_level, *m_impl->m_dataset_name, m_impl->makeKeyStringFromRunNumber(), keys, 1); if(s == 0) return Run(); - size_t i = m_impl->m_container->size()+1; + size_t i = m_impl->m_dataset_name->size()+1; if(keys[0].size() <= i) return Run(); - RunNumber rn = Impl::parseRunNumberFromKeyString(&keys[0][i]); + RunNumber rn = parseNumberFromKeyString(&keys[0][i]); if(rn == InvalidRunNumber) return Run(); - return Run(m_impl->m_datastore, m_impl->m_level, m_impl->m_container, rn); + return Run(m_impl->m_datastore, m_impl->m_level, + m_impl->m_dataset_name, rn); } bool Run::valid() const { @@ -101,10 +104,11 @@ bool Run::operator==(const Run& other) const { if(!v1 && !v2) return true; if(v1 && !v2) return false; if(!v1 && v2) return false; - return m_impl->m_datastore == other.m_impl->m_datastore - && m_impl->m_level == other.m_impl->m_level - && *m_impl->m_container == *other.m_impl->m_container - && m_impl->m_run_nr == other.m_impl->m_run_nr; + return m_impl->m_datastore == other.m_impl->m_datastore + && m_impl->m_level == other.m_impl->m_level + && (m_impl->m_dataset_name == other.m_impl->m_dataset_name + || *m_impl->m_dataset_name == *other.m_impl->m_dataset_name) + && m_impl->m_run_number == other.m_impl->m_run_number; } bool Run::operator!=(const Run& other) const { @@ -115,14 +119,14 @@ const RunNumber& Run::number() const { if(!valid()) { throw Exception("Calling Run member function on an invalid Run object"); } - return m_impl->m_run_nr; + return m_impl->m_run_number; } const std::string& Run::container() const { if(!valid()) { throw Exception("Calling Run member function on an invalid Run object"); } - return *m_impl->m_container; + return *m_impl->m_dataset_name; } SubRun Run::createSubRun(const SubRunNumber& subRunNumber) { @@ -130,7 +134,7 @@ SubRun Run::createSubRun(const SubRunNumber& subRunNumber) { throw Exception("Calling Run member function on an invalid Run object"); } std::string parent = m_impl->fullpath(); - std::string subRunStr = SubRun::Impl::makeKeyStringFromSubRunNumber(subRunNumber); + std::string subRunStr = makeKeyStringFromNumber(subRunNumber); m_impl->m_datastore->m_impl->store(m_impl->m_level+1, parent, subRunStr); return SubRun(m_impl->m_datastore, m_impl->m_level+1, std::make_shared(parent), subRunNumber); @@ -141,7 +145,7 @@ SubRun Run::createSubRun(WriteBatch& batch, const SubRunNumber& subRunNumber) { throw Exception("Calling Run member function on an invalid Run object"); } std::string parent = m_impl->fullpath(); - std::string subRunStr = SubRun::Impl::makeKeyStringFromSubRunNumber(subRunNumber); + std::string subRunStr = makeKeyStringFromNumber(subRunNumber); batch.m_impl->store(m_impl->m_level+1, parent, subRunStr); return SubRun(m_impl->m_datastore, m_impl->m_level+1, std::make_shared(parent), subRunNumber); @@ -160,7 +164,7 @@ Run::iterator Run::find(const SubRunNumber& subRunNumber) { } int ret; std::string parent = m_impl->fullpath(); - std::string subRunStr = SubRun::Impl::makeKeyStringFromSubRunNumber(subRunNumber); + std::string subRunStr = makeKeyStringFromNumber(subRunNumber); bool b = m_impl->m_datastore->m_impl->exists(m_impl->m_level+1, parent, subRunStr); if(!b) { return m_impl->m_end; diff --git a/src/RunImpl.hpp b/src/RunImpl.hpp index 87ee061d74ffc957854861e55ab7dc84edfbd2ea..80ce90293c1cc47a58b2d546578358780fea7f25 100644 --- a/src/RunImpl.hpp +++ b/src/RunImpl.hpp @@ -10,6 +10,7 @@ #include #include #include "hepnos/Run.hpp" +#include "NumberUtil.hpp" namespace hepnos { @@ -17,68 +18,27 @@ class Run::Impl { public: - DataStore* m_datastore; - uint8_t m_level; - std::shared_ptr m_container; - RunNumber m_run_nr; - iterator m_end; + DataStore* m_datastore; + uint8_t m_level; + std::shared_ptr m_dataset_name; + RunNumber m_run_number; - Impl(DataStore* ds, uint8_t level, const std::shared_ptr& container, const RunNumber& rn) + static iterator m_end; + + Impl(DataStore* ds, uint8_t level, + const std::shared_ptr& dataset, + const RunNumber& rn) : m_datastore(ds) , m_level(level) - , m_container(container) - , m_run_nr(rn) {} - - static std::string makeKeyStringFromRunNumber(const RunNumber& n) { - std::string str(1+sizeof(n),'\0'); - str[0] = '%'; -#ifndef HEPNOS_READABLE_NUMBERS -#if BOOST_ENDIAN_BIG_BYTE - std::memcpy(&str[1], &n, sizeof(n)); - return str; -#else - unsigned i = sizeof(n); - auto n2 = n; - while(n2 != 0) { - str[i] = n2 & 0xff; - n2 = n2 >> 8; - i -= 1; - } - return str; -#endif -#else - std::stringstream strstr; - strstr << "%" << std::setfill('0') << std::setw(16) << std::hex << n; - return strstr.str(); -#endif - } - - static RunNumber parseRunNumberFromKeyString(const char* str) { - if(str[0] != '%') return InvalidRunNumber; - RunNumber n; -#ifdef HEPNOS_READABLE_NUMBERS - std::stringstream strRunNumber; - strRunNumber << std::hex << std::string(str+1, 16); - strRunNumber >> n; -#else -#if BOOST_ENDIAN_BIG_BYTE - std::memcpy(&n, &str[1], sizeof(n)); -#else - n = 0; - for(unsigned i=0; i < sizeof(n); i++) { - n = 256*n + str[i+1]; - } -#endif -#endif - return n; - } + , m_dataset_name(dataset) + , m_run_number(rn) {} std::string makeKeyStringFromRunNumber() const { - return makeKeyStringFromRunNumber(m_run_nr); + return makeKeyStringFromNumber(m_run_number); } std::string fullpath() const { - return *m_container + std::string("/") + makeKeyStringFromRunNumber(m_run_nr); + return *m_dataset_name + std::string("/") + makeKeyStringFromRunNumber(); } }; diff --git a/src/RunSet.cpp b/src/RunSet.cpp index 5503e0da6e664e63646372bc9e717fa3e311f119..9d596eb65c73341a537d0390da05ccfc4c60764d 100644 --- a/src/RunSet.cpp +++ b/src/RunSet.cpp @@ -35,7 +35,7 @@ Run RunSet::operator[](const RunNumber& runNumber) { RunSet::iterator RunSet::find(const RunNumber& runNumber) { int ret; std::string parent = m_impl->m_dataset->fullname(); - std::string strNum = Run::Impl::makeKeyStringFromRunNumber(runNumber); + std::string strNum = makeKeyStringFromNumber(runNumber); auto datastore = m_impl->m_dataset->m_impl->m_datastore; auto level = m_impl->m_dataset->m_impl->m_level; bool b = datastore->m_impl->exists(level+1, parent, strNum); diff --git a/src/SubRun.cpp b/src/SubRun.cpp index b8d2b29a2a124e066be47ed55df89e107b8158a9..d7bc1180d29d1f71cce59bfaa9a966cc5fe6c60b 100644 --- a/src/SubRun.cpp +++ b/src/SubRun.cpp @@ -56,7 +56,7 @@ SubRun SubRun::next() const { if(s == 0) return SubRun(); size_t i = m_impl->m_container->size()+1; if(keys[0].size() <= i) return SubRun(); - SubRunNumber rn = Impl::parseSubRunNumberFromKeyString(&keys[0][i]); + SubRunNumber rn = parseNumberFromKeyString(&keys[0][i]); if(rn == InvalidSubRunNumber) return SubRun(); return SubRun(m_impl->m_datastore, m_impl->m_level, m_impl->m_container, rn); } @@ -122,7 +122,7 @@ Event SubRun::createEvent(const EventNumber& eventNumber) { throw Exception("Calling SubRun member function on invalid SubRun object"); } std::string parent = m_impl->fullpath(); - std::string eventStr = Event::Impl::makeKeyStringFromEventNumber(eventNumber); + std::string eventStr = makeKeyStringFromNumber(eventNumber); m_impl->m_datastore->m_impl->store(m_impl->m_level+1, parent, eventStr); return Event(m_impl->m_datastore, m_impl->m_level+1, std::make_shared(parent), eventNumber); @@ -133,7 +133,7 @@ Event SubRun::createEvent(WriteBatch& batch, const EventNumber& eventNumber) { throw Exception("Calling SubRun member function on invalid SubRun object"); } std::string parent = m_impl->fullpath(); - std::string eventStr = Event::Impl::makeKeyStringFromEventNumber(eventNumber); + std::string eventStr = makeKeyStringFromNumber(eventNumber); batch.m_impl->store(m_impl->m_level+1, parent, eventStr); return Event(m_impl->m_datastore, m_impl->m_level+1, std::make_shared(parent), eventNumber); @@ -152,7 +152,7 @@ SubRun::iterator SubRun::find(const EventNumber& eventNumber) { } int ret; std::string parent = m_impl->fullpath(); - std::string eventStr = Event::Impl::makeKeyStringFromEventNumber(eventNumber); + std::string eventStr = makeKeyStringFromNumber(eventNumber); bool b = m_impl->m_datastore->m_impl->exists(m_impl->m_level+1, parent, eventStr); if(!b) { return m_impl->m_end; diff --git a/src/SubRunImpl.hpp b/src/SubRunImpl.hpp index 2a6e91882f28bbb60569c1ff2c477dfaf9c1c7ee..94873d18aeb0b9149ff8bcce7729d82612d108a0 100644 --- a/src/SubRunImpl.hpp +++ b/src/SubRunImpl.hpp @@ -10,6 +10,7 @@ #include #include #include "hepnos/SubRun.hpp" +#include "NumberUtil.hpp" namespace hepnos { @@ -29,52 +30,8 @@ class SubRun::Impl { , m_container(container) , m_subrun_nr(rn) {} - static std::string makeKeyStringFromSubRunNumber(const SubRunNumber& n) { - std::string str(1+sizeof(n),'\0'); - str[0] = '%'; -#ifndef HEPNOS_READABLE_NUMBERS -#if BOOST_ENDIAN_BIG_BYTE - std::memcpy(&str[1], &n, sizeof(n)); - return str; -#else - unsigned i = sizeof(n); - auto n2 = n; - while(n2 != 0) { - str[i] = n2 & 0xff; - n2 = n2 >> 8; - i -= 1; - } - return str; -#endif -#else - std::stringstream strstr; - strstr << "%" << std::setfill('0') << std::setw(16) << std::hex << n; - return strstr.str(); -#endif - } - - static SubRunNumber parseSubRunNumberFromKeyString(const char* str) { - if(str[0] != '%') return InvalidSubRunNumber; - SubRunNumber n; -#ifdef HEPNOS_READABLE_NUMBERS - std::stringstream strSubRunNumber; - strSubRunNumber << std::hex << std::string(str+1, 16); - strSubRunNumber >> n; -#else -#if BOOST_ENDIAN_BIG_BYTE - std::memcpy(&n, &str[1], sizeof(n)); -#else - n = 0; - for(unsigned i=0; i < sizeof(n); i++) { - n = 256*n + str[i+1]; - } -#endif -#endif - return n; - } - std::string makeKeyStringFromSubRunNumber() const { - return makeKeyStringFromSubRunNumber(m_subrun_nr); + return makeKeyStringFromNumber(m_subrun_nr); } std::string fullpath() const {