Commit 070d5c58 authored by Matthieu Dorier's avatar Matthieu Dorier
Browse files

added EventSet and test for EventSet

parent c2c42bdb
......@@ -369,7 +369,7 @@ class DataSet : public KeyValueContainer {
/**
* @brief Returns the RunSet associated with this DataSet.
*
* @return a reference to the RunSet associated with this DataSet.
* @return the RunSet associated with this DataSet.
*/
RunSet runs() const;
......@@ -384,6 +384,17 @@ class DataSet : public KeyValueContainer {
* @return a Run corresponding to the provided run number.
*/
Run operator[](const RunNumber& runNumber) const;
/**
* @brief Returns an EventSet pointing to Events in
* the specified target. If target is -1, the EventSet
* will also iterate over targets.
*
* @param target Target index in which to find events.
*
* @return an EventSet associated with the DataSet.
*/
EventSet events(int target=-1) const;
};
class DataSet::const_iterator {
......
......@@ -9,6 +9,7 @@
#include <vector>
#include <string>
#include <memory>
#include <hepnos/ItemType.hpp>
namespace hepnos {
......@@ -167,6 +168,16 @@ class DataStore {
*/
void shutdown();
/**
* @brief Returns the number of underlying targets for the
* specified item type.
*
* @param type Item type.
*
* @return The number of targets for the item type.
*/
size_t numTargets(const ItemType& type) const;
private:
/**
......
......@@ -88,41 +88,6 @@ class EventSet {
*/
DataStore datastore() const;
/**
* @brief Searches this EventSet for an Event with
* the provided run, subrun, and event number and returns
* an iterator to it if found, otherwise it returns an iterator
* pointing to EventSet::end().
*
* @param runNumber Run number of the Event to find.
* @param subrunNumber SubRun number of the Event to find.
* @param eventNumber Event number of the Event to find.
*
* @return an iterator pointing to the Run if found,
* EventSet::end() otherwise.
*/
iterator find(const RunNumber& runNumber,
const SubRunNumber& subrunNumber,
const EventNumber& eventNumber);
/**
* @brief Searches this EventSet for an Event with
* the provided run, subrun, and event number and returns a
* const_iterator to it if found, otherwise it returns an iterator
* pointing to EventSet::cend().
*
* @param runNumber Run number of the Event to find.
* @param subrunNumber SubRun number of the Event to find.
* @param eventNumber Event number of the Event to find.
*
* @return a const_iterator pointing to the Event if found,
* EventSet::cend() otherwise.
*/
const_iterator find(const RunNumber& runNumber,
const SubRunNumber& subrunNumber,
const EventNumber& eventNumber) const;
/**
* @brief Returns an iterator referring to the first Event
* in this EventSet.
......@@ -174,77 +139,12 @@ class EventSet {
*/
const_iterator cend() const;
/**
* @brief Returns an iterator pointing to the first Event in this
* EventSet, whose run, subrun, end event numbers is equal or greater
* than the lower bounds.
*
* @param lb_run Lower bound Run number.
* @param lb_subrun Lower bound SubRun number.
* @param lb_event Lower bound Event number.
*
* @return An iterator to the first Event in this EventSet
* whose number is equal or greater than lower bounds or EventSet::end()
* if such an Event does not exist.
*/
iterator lower_bound(const RunNumber& lb_run,
const SubRunNumber& lb_subrun,
const EventNumber& lb_event);
/**
* @brief Returns a const_iterator pointing to the first Event in this
* EventSet, whose run, subrun, end event numbers is equal or greater
* than the lower bounds.
*
* @param lb_run Lower bound Run number.
* @param lb_subrun Lower bound SubRun number.
* @param lb_event Lower bound Event number.
*
* @return An iterator to the first Event in this EventSet
* whose number is equal or greater than lower bounds or EventSet::end()
* if such an Event does not exist.
*/
const_iterator lower_bound(const RunNumber& lb_run,
const SubRunNumber& lb_subrun,
const EventNumber& lb_event) const;
/**
* @brief Returns an iterator pointing to the first Event in the
* EventSet whose run, subrun, and event number are strictly greater than
* the provided upper bounds.
*
* @param ub_run Upper bound Run number.
* @param ub_subrun Upper bound SubRun number.
* @param ub_event Upper bound Event number.
*
* @return An iterator to the the first Event in this EventSet,
* whose number is stricly greater than provided upper bound, or
* EventSet::end() if no such an Event exist.
*/
iterator upper_bound(const RunNumber& ub_run,
const SubRunNumber& ub_subrun,
const EventNumber& ub_event);
/**
* @brief Returns a const_iterator pointing to the first Event in the
* EventSet whose run, subrun, and event number are strictly greater than
* the provided upper bounds.
*
* @param ub_run Upper bound Run number.
* @param ub_subrun Upper bound SubRun number.
* @param ub_event Upper bound Event number.
*
* @return An iterator to the the first Event in this EventSet,
* whose number is stricly greater than provided upper bound, or
* EventSet::end() if no such an Event exist.
*/
const_iterator upper_bound(const RunNumber& ub_run,
const SubRunNumber& ub_subrun,
const EventNumber& ub_event) const;
};
class EventSet::const_iterator {
friend class EventSet;
protected:
/**
......@@ -253,6 +153,8 @@ class EventSet::const_iterator {
class Impl;
std::unique_ptr<Impl> m_impl; /*!< Pointer to implementation */
const_iterator(std::unique_ptr<Impl>&& impl);
public:
/**
* @brief Constructor. Creates a const_iterator pointing
......@@ -260,22 +162,6 @@ class EventSet::const_iterator {
*/
const_iterator();
/**
* @brief Constructor. Creates a const_iterator pointing
* to a given Run. The Run may or may not be valid.
*
* @param current Run to make the const_iterator point to.
*/
const_iterator(const Event& current);
/**
* @brief Constructor. Creates a const_iterator pointing
* to a given Event. The Event may or may not be valid.
*
* @param current Event to make the const_iterator point to.
*/
const_iterator(Event&& current);
typedef const_iterator self_type;
typedef Event value_type;
typedef Event& reference;
......@@ -379,6 +265,12 @@ class EventSet::const_iterator {
class EventSet::iterator : public EventSet::const_iterator {
friend class EventSet;
private:
iterator(std::unique_ptr<EventSet::const_iterator::Impl>&& impl);
public:
/**
......@@ -387,22 +279,6 @@ class EventSet::iterator : public EventSet::const_iterator {
*/
iterator();
/**
* @brief Constructor. Builds an iterator pointing to
* an existing Event. The Event may or may not be valid.
*
* @param current Event to point to.
*/
iterator(const Event& current);
/**
* @brief Constructor. Builds an iterator pointing to
* an existing Event. The Run may or may not be valid.
*
* @param current DataSet to point to.
*/
iterator(Event&& current);
typedef iterator self_type;
typedef Event value_type;
typedef Event& reference;
......
......@@ -7,7 +7,8 @@ enum class ItemType : uint32_t {
DATASET,
RUN,
SUBRUN,
EVENT
EVENT,
PRODUCT
};
}
......
......@@ -9,6 +9,7 @@
#include "hepnos/AsyncEngine.hpp"
#include "ItemImpl.hpp"
#include "DataSetImpl.hpp"
#include "EventSetImpl.hpp"
#include "DataStoreImpl.hpp"
#include "AsyncEngineImpl.hpp"
#include "WriteBatchImpl.hpp"
......@@ -337,6 +338,18 @@ RunSet DataSet::runs() const {
return RunSet(m_impl);
}
EventSet DataSet::events(int target) const {
if(!valid()) {
throw Exception("Calling DataSet member function on an invalid DataSet");
}
if(target >= 0)
return EventSet(std::make_shared<EventSetImpl>(*m_impl, target));
else {
auto numTargets = m_impl->m_datastore->numTargets(ItemType::EVENT);
return EventSet(std::make_shared<EventSetImpl>(*m_impl, 0, numTargets));
}
}
////////////////////////////////////////////////////////////////////////////////////////////
// DataSet::const_iterator::Impl implementation
////////////////////////////////////////////////////////////////////////////////////////////
......
......@@ -73,5 +73,12 @@ bool DataStore::loadRawProduct(const ProductID& productID, char* data, size_t* s
return m_impl->loadRawProduct(productID, data, size);
}
size_t DataStore::numTargets(const ItemType& type) const {
if(!m_impl) {
throw Exception("Calling DataStore member function on an invalid DataStore object");
}
return m_impl->numTargets(type);
}
}
......@@ -20,7 +20,6 @@
#include "StringHash.hpp"
#include "DataSetImpl.hpp"
#include "ItemImpl.hpp"
#include "ItemType.hpp"
namespace hepnos {
......@@ -155,6 +154,22 @@ class DataStoreImpl {
if(m_mid) margo_finalize(m_mid);
}
size_t numTargets(const ItemType& type) const {
switch(type) {
case ItemType::DATASET:
return m_dataset_dbs.dbs.size();
case ItemType::RUN:
return m_run_dbs.dbs.size();
case ItemType::SUBRUN:
return m_subrun_dbs.dbs.size();
case ItemType::EVENT:
return m_event_dbs.dbs.size();
case ItemType::PRODUCT:
return m_product_dbs.dbs.size();
}
return 0;
}
private:
static void checkConfig(YAML::Node& config) {
......@@ -477,8 +492,13 @@ class DataStoreImpl {
// Access functions for numbered items (Runs, SubRuns, and Events)
///////////////////////////////////////////////////////////////////////////
const sdskv::database& locateItemDb(const ItemType& type, const ItemDescriptor& id) const {
const sdskv::database& locateItemDb(const ItemType& type, const ItemDescriptor& id, int target=-1) const {
long unsigned db_idx = 0;
if(target >= 0) {
if(type == ItemType::RUN) return m_run_dbs.dbs[target];
if(type == ItemType::SUBRUN) return m_subrun_dbs.dbs[target];
if(type == ItemType::EVENT) return m_event_dbs.dbs[target];
}
uint64_t hash;
size_t prime = 1099511628211ULL;
hash = id.dataset.hash();
......@@ -508,11 +528,12 @@ class DataStoreImpl {
const ItemType& prefix_type,
const std::shared_ptr<ItemImpl>& current,
std::vector<std::shared_ptr<ItemImpl>>& result,
size_t maxItems) const {
size_t maxItems,
int target=-1) const {
int ret;
result.resize(0);
const ItemDescriptor& start_key = current->m_descriptor;
auto& db = locateItemDb(item_type, start_key);
auto& db = locateItemDb(item_type, start_key, target);
// ignore keys that don't have the same uuid
// issue an sdskv_list_keys
std::vector<ItemDescriptor> descriptors(maxItems);
......@@ -543,7 +564,8 @@ class DataStoreImpl {
bool itemExists(const UUID& containerUUID,
const RunNumber& run_number,
const SubRunNumber& subrun_number = InvalidSubRunNumber,
const EventNumber& event_number = InvalidEventNumber) const {
const EventNumber& event_number = InvalidEventNumber,
int target = -1) const {
// build the key
ItemDescriptor k;
k.dataset = containerUUID;
......@@ -557,7 +579,7 @@ class DataStoreImpl {
type = ItemType::EVENT;
}
// find out which DB to access
auto& db = locateItemDb(type, k);
auto& db = locateItemDb(type, k, target);
try {
bool b = db.exists(&k, sizeof(k));
return b;
......
......@@ -14,158 +14,50 @@
namespace hepnos {
////////////////////////////////////////////////////////////////////////////////////////////
// EventSet implementation
////////////////////////////////////////////////////////////////////////////////////////////
static EventSet::iterator EventSet_end;
EventSet::EventSet(const std::shared_ptr<EventSetImpl>& impl)
: m_impl(impl) {}
EventSet::EventSet(std::shared_ptr<EventSetImpl>&& impl)
: m_impl(std::move(impl)) {}
DataStore EventSet::datastore() const {
return DataStore(m_impl->m_datastore);
}
EventSet::iterator EventSet::find(const RunNumber& runNumber,
const SubRunNumber& subrunNumber,
const EventNumber& eventNumber) {
int ret;
auto& datastore = m_impl->m_datastore;
bool b = datastore->itemExists(m_impl->m_uuid, runNumber, subrunNumber, eventNumber);
if(!b) return end();
return iterator(
std::make_shared<ItemImpl>(
datastore,
m_impl->m_uuid,
runNumber));
}
EventSet::const_iterator EventSet::find(const RunNumber& runNumber,
const SubRunNumber& subrunNumber,
const EventNumber& eventNumber) const {
iterator it = const_cast<EventSet*>(this)->find(runNumber, subrunNumber, eventNumber);
return it;
}
EventSet::iterator EventSet::begin() {
auto it = find(0,0,0);
if(it != end()) return *it;
auto ds_level = m_impl->m_level;
auto datastore = m_impl->m_datastore;
auto new_event_impl = std::make_shared<ItemImpl>(datastore, m_impl->m_uuid, 0, 0, 0);
Event event(std::move(new_event_impl));
event = event.next();
if(event.valid()) return iterator(event);
else return end();
}
EventSet::iterator EventSet::end() {
return EventSet_end;
}
EventSet::const_iterator EventSet::cbegin() const {
return const_iterator(const_cast<EventSet*>(this)->begin());
}
EventSet::const_iterator EventSet::cend() const {
return EventSet_end;
}
EventSet::const_iterator EventSet::begin() const {
return const_iterator(const_cast<EventSet*>(this)->begin());
}
EventSet::const_iterator EventSet::end() const {
return EventSet_end;
}
EventSet::iterator EventSet::lower_bound(const RunNumber& lb_run,
const SubRunNumber& lb_subrun,
const EventNumber& lb_event) {
if(lb_run == 0 && lb_subrun == 0 && lb_event == 0) {
auto it = find(0,0,0);
if(it != end()) {
return it;
} else {
Event event(std::make_shared<ItemImpl>(
m_impl->m_datastore,
m_impl->m_uuid, 0, 0, 0));
event = event.next();
if(!event.valid()) return end();
else return iterator(event);
}
} else {
// XXX the bellow is actually not correct
auto it = find(lb_run, lb_subrun, lb_event-1);
if(it != end()) {
++it;
return it;
}
Event event(std::make_shared<ItemImpl>(
m_impl->m_datastore,
m_impl->m_uuid, lb_event-1));
event = event.next();
if(!event.valid()) return end();
else return iterator(event);
}
}
EventSet::const_iterator EventSet::lower_bound(const RunNumber& lb_run,
const SubRunNumber& lb_subrun,
const EventNumber& lb_event) const {
iterator it = const_cast<EventSet*>(this)->lower_bound(lb_run, lb_subrun, lb_event);
return it;
}
EventSet::iterator EventSet::upper_bound(const RunNumber& ub_run,
const SubRunNumber& ub_subrun,
const EventNumber& ub_event) {
Event event(std::make_shared<ItemImpl>(m_impl->m_datastore,
m_impl->m_uuid, ub_run, ub_subrun, ub_event));
event = event.next();
if(!event.valid()) return end();
else return iterator(event);
}
EventSet::const_iterator EventSet::upper_bound(const RunNumber& ub_run,
const SubRunNumber& ub_subrun,
const EventNumber& ub_event) const {
iterator it = const_cast<EventSet*>(this)->upper_bound(ub_run, ub_subrun, ub_event);
return it;
}
////////////////////////////////////////////////////////////////////////////////////////////
// EventSet::const_iterator::Impl implementation
////////////////////////////////////////////////////////////////////////////////////////////
class EventSet::const_iterator::Impl {
friend class EventSet;
public:
Event m_current_event;
int m_target = 0;
int m_num_targets = 0;
Impl()
: m_current_event()
{}
Impl(const Event& event)
Impl(const Event& event, int target, int num_targets=0)
: m_current_event(event)
, m_target(target)
, m_num_targets(num_targets)
{}
Impl(Event&& event)
Impl(Event&& event, int target, int num_targets=0)
: m_current_event(std::move(event))
, m_target(target)
, m_num_targets(num_targets)
{}
Impl(const Impl& other)
: m_current_event(other.m_current_event)
, m_target(other.m_target)
, m_num_targets(other.m_num_targets)
{}
bool operator==(const Impl& other) const {
return m_current_event == other.m_current_event;
auto v1 = m_current_event.valid();
auto v2 = other.m_current_event.valid();
if(!v1 && !v2) return true;
if(!v1 && v2) return false;
if(v1 && !v2) return false;
return m_current_event == other.m_current_event
&& m_target == other.m_target
&& m_num_targets == other.m_num_targets;
}
};
......@@ -176,11 +68,8 @@ class EventSet::const_iterator::Impl {
EventSet::const_iterator::const_iterator()
: m_impl(std::make_unique<Impl>()) {}
EventSet::const_iterator::const_iterator(const Event& event)
: m_impl(std::make_unique<Impl>(event)) {}
EventSet::const_iterator::const_iterator(Event&& event)
: m_impl(std::make_unique<Impl>(std::move(event))) {}
EventSet::const_iterator::const_iterator(std::unique_ptr<Impl>&& impl)
: m_impl(std::move(impl)) {}
EventSet::const_iterator::~const_iterator() {}
......@@ -206,7 +95,56 @@ EventSet::const_iterator::self_type EventSet::const_iterator::operator++() {
if(!m_impl) {
throw Exception("Trying to increment an invalid iterator");
}
m_impl->m_current_event = m_impl->m_current_event.next();
if(!(m_impl->m_current_event.valid())) {
throw Exception("Trying to increment an iterator past the end of the EventSet");
}
std::vector<std::shared_ptr<ItemImpl>> next_events;
auto& ds = m_impl->m_current_event.m_impl->m_datastore;
if(m_impl->m_num_targets == 0) { // single target access
size_t s = ds->nextItems(ItemType::EVENT, ItemType::DATASET,
m_impl->m_current_event.m_impl,
next_events, 1, m_impl->m_target);
if(s != 0) {
m_impl->m_current_event.m_impl = std::move(next_events[0]);
} else {
m_impl->m_current_event = Event();
}
} else { // multi-target access
// try to get next event from current target
size_t s = ds->nextItems(ItemType::EVENT, ItemType::DATASET,
m_impl->m_current_event.m_impl,
next_events, 1, m_impl->m_target);
if(s == 1) {
// event found
m_impl->m_current_event.m_impl = std::move(next_events[0]);
return *this;
}
// event not found, incrementing target
m_impl->m_target += 1;
// start looping over targets
while(m_impl->m_target < m_impl->m_num_targets) {
// search for event (0,0,0)
auto& uuid = m_impl->m_current_event.m_impl->m_descriptor.dataset;
auto event_impl000 = std::make_shared<ItemImpl>(ds, uuid, 0, 0, 0);
if(ds->itemExists(uuid, 0, 0, 0, m_impl->m_target)) {
// there exists an item 0,0,0; make the iterator point to it
m_impl->m_current_event.m_impl = std::move(event_impl000);
return *this;
}
// if event (0,0,0) does not exist, then try to get the next one
size_t s = ds->nextItems(ItemType::EVENT, ItemType::DATASET,
event_impl000, next_events, 1, m_impl->m_target);
if(s == 1) {
// item found, make the iterator point to it
m_impl->m_current_event.m_impl = std::move(next_events[0]);
return *this;
}
m_impl->m_target += 1;
}
// if we get out of the loop, we haven't found any event
m_impl->m_current_event = Event();
}
return *this;
}