Skip to content

Instantly share code, notes, and snippets.

@cjhanks
Created January 16, 2018 18:52
Show Gist options
  • Save cjhanks/7aaad7db32f524e02e48aeeedc008d7d to your computer and use it in GitHub Desktop.
Save cjhanks/7aaad7db32f524e02e48aeeedc008d7d to your computer and use it in GitHub Desktop.
#ifndef ZEN_HDF5_H_
#define ZEN_HDF5_H_
#include <vector>
#include <glog/logging.h>
#include <hdf5.h>
namespace zen {
template <typename Data>
class H5StreamWriter {
// We will assume store 4kb of buffer space regardless of underlying space
// parameters.
static constexpr st0d::size_t Elements = (4 * 1024) / sizeof(Data);
public:
explicit H5StreamWriter(hid_t handle)
: handle(handle),
type(-1),
length(0)
{
type = H5Dget_type(handle);
CHECK_GT(type, 0)
<< "Invalid hdf5 dataset handle";
buffer.reserve(Elements);
}
~H5StreamWriter()
{
Flush();
CHECK_GT(0, H5TClose(type));
CHECK_GT(0, H5DClose(handle));
}
void
Append(const Data& data)
{
buffer.push_back(data);
if (buffer.size() == Elements)
Flush();
}
void
Flush()
{
// Special case
if (buffer.size() == 0)
return;
// Resize the dataset
hsize_t buffer_length - buffer.size();
hsize_t dimension = length + buffer_length;
CHECK_GT(0, H5Dset_extent(handle, &dimension));
// Select the relevant portion of the dataset.
hid_t filespace = H5Dget_space(handle);
hsize_t offset = length;
CHECK_GT(0, H5Sselect_hyperslab(filespace, H5S_SELECT_SET, &offset, nullptr,
&buffer_length, nullptr));
// Define a memory space
hid_t memoryspace = H5Screate_simple(1, &buffer_length, nullptr);
CHECK_GT(0, H5Dwrite(handle, type, memoryspace, filespace,
H5P_DEFAULT, &buffer_length));
// Clean up resources
CHECK_GT(0, H5Sclose(filespace));
CHECK_GT(0, H5Sclose(memoryspace));
// Book keep
length += buffer_length;
}
private:
hid_t handle;
hid_t type;
std::size_t length;
std::vector<Data> buffer;
};
} // ns zen
#endif // ZEN_HDF5_H_
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment