13 template <
typename AtomicType>
14 class Branch<AtomicType, std::enable_if_t<is_atomic_v<AtomicType>>>
18 HighFive::DataSet set_;
19 std::vector<AtomicType> buffer_;
21 std::size_t i_memory_;
49 std::size_t request_len = this->max_len_;
50 if (request_len + i_file_ > entries_) {
51 request_len = entries_ - i_file_;
52 assert(request_len >= 0);
55 if constexpr (std::is_same_v<AtomicType, bool>) {
61 std::vector<Bool> buff;
62 buff.resize(request_len);
63 this->set_.select({i_file_}, {request_len})
65 buffer_.reserve(buff.size());
66 for (
const auto& v : buff) buffer_.push_back(v == Bool::TRUE);
68 this->set_.select({i_file_}, {request_len}).read(buffer_);
71 i_file_ += buffer_.size();
76 explicit ReadBuffer(std::size_t max, HighFive::DataSet s)
77 : max_len_{max}, set_{s}, buffer_{}, i_file_{0}, i_memory_{0} {
78 entries_ = this->set_.getDimensions().at(0);
79 this->read_chunk_from_disk();
82 void read(AtomicType& v) {
83 if (i_memory_ == buffer_.size()) this->read_chunk_from_disk();
84 v = buffer_[i_memory_];
88 std::unique_ptr<ReadBuffer> read_buffer_;
92 HighFive::DataSet set_;
93 std::vector<AtomicType> buffer_;
125 if (buffer_.size() == 0)
return;
126 std::size_t new_extent = i_file_ + buffer_.size();
128 if (this->set_.getDimensions().at(0) < new_extent) {
129 this->set_.resize({new_extent});
131 if constexpr (std::is_same_v<AtomicType, bool>) {
133 std::vector<Bool> buff;
134 buff.reserve(buffer_.size());
135 for (
const auto& v : buffer_)
136 buff.push_back(v ? Bool::TRUE : Bool::FALSE);
137 this->set_.select({i_file_}, {buffer_.size()}).write(buff);
139 this->set_.select({i_file_}, {buffer_.size()}).write(buffer_);
141 i_file_ += buffer_.size();
143 buffer_.reserve(this->max_len_);
160 : max_len_{max}, set_{s}, buffer_{}, i_file_{0} {
161 buffer_.reserve(this->max_len_);
165 ~WriteBuffer() { flush(); }
175 void save(
const AtomicType& val) {
176 buffer_.push_back(val);
177 if (buffer_.size() > this->max_len_) flush();
181 std::unique_ptr<WriteBuffer> write_buffer_;
191 explicit Branch(
const std::string& branch_name, AtomicType* handle =
nullptr)
197 std::make_unique<ReadBuffer>(10000, f.getDataSet(this->name_));
198 }
catch (
const HighFive::DataSetException& e) {
200 std::stringstream msg, help;
201 msg <<
"HDTreeBadType: Branch at " << this->
name_
202 <<
" could not be accessed.";
203 help <<
"Check that this branch exists in your HDTree.\n"
204 " H5 Error: " << e.what();
217 if (read_buffer_) read_buffer_->read(*(this->
handle_));
229 if (write_buffer_) write_buffer_->save(*(this->
handle_));
239 HighFive::DataType t;
240 if constexpr (std::is_same_v<AtomicType, bool>) {
243 t = HighFive::AtomicType<AtomicType>();
245 auto ds = f.createDataSet(this->name_, t);
247 boost::core::demangle(
typeid(AtomicType).name()));
250 write_buffer_ = std::make_unique<WriteBuffer>(f.getRowsPerChunk(), ds);
251 }
catch (
const HighFive::DataSetException& e) {
253 std::stringstream msg, help;
254 msg <<
"HDTreeBadType: Branch at " << this->name_
255 <<
" could not be created.";
256 help <<
"Check that this branch does not already exist in your HDTree.\n"
257 " H5 Error: " << e.what();
Type-specific base class to hold common data methods.
Definition: AbstractBranch.h:87
DataType * handle_
handle on current object in memory
Definition: AbstractBranch.h:247
std::string name_
name of branch
Definition: AbstractBranch.h:74
void read_chunk_from_disk()
Load the next chunk of data into memory.
Definition: AtomicBranch.h:46
void save(const AtomicType &val)
Put the new value into the buffer.
Definition: AtomicBranch.h:175
WriteBuffer(std::size_t max, HighFive::DataSet s)
Define the buffer size and the set we will write to.
Definition: AtomicBranch.h:159
void flush()
Flush our in-memory buffer onto disk.
Definition: AtomicBranch.h:124
void attach(Writer &f) final override
do NOT persist any structure for atomic types
Definition: AtomicBranch.h:238
void load() final override
Down to a type that Reader can handle.
Definition: AtomicBranch.h:216
Branch(const std::string &branch_name, AtomicType *handle=nullptr)
We don't do any more initialization except which is handled by the AbstractBranch.
Definition: AtomicBranch.h:191
void attach(Reader &f) final override
pure virtual method for loading data from the input file
Definition: AtomicBranch.h:194
void save() final override
Down to a type that io::Writer can handle.
Definition: AtomicBranch.h:228
General data set.
Definition: GeneralBranch.h:46
user-facing exception class for hdtree
Definition: Exception.h:15
Reading a file generated by fire.
Definition: Reader.h:24
Write the fire DataSets into a deterministic structure in the output HDF5 data file.
Definition: Writer.h:21
Geant4 does a GLOBAL definition of the keyword TRUE.
Definition: Atomic.cxx:3
HighFive::EnumType< Bool > create_enum_bool()
HighFive method for creating the enum data type.
Definition: Atomic.cxx:5
static const std::string TYPE_ATTR_NAME
the name of the HDF5 object attribute that holds the event object type
Definition: Constants.h:17
static const std::string VERS_ATTR_NAME
the name of the hdtree version attribute
Definition: Constants.h:19