Commit 4a73fb8c authored by gbalduzz's avatar gbalduzz
Browse files

Merge branch 'hdf5_cleanup' into write_config_timestamps

parents 089184c9 02bc73e6
Loading
Loading
Loading
Loading
+8 −17
Original line number Diff line number Diff line
@@ -39,7 +39,9 @@ public:

public:
  // In: verbose. If true, the writer outputs a short log whenever it is executed.
  HDF5Writer(bool verbose = true) : file_id(-1), my_paths(0), verbose_(verbose) {}
  HDF5Writer(bool verbose = true) : verbose_(verbose) {
    H5::Exception::dontPrint();
  }

  ~HDF5Writer();

@@ -50,7 +52,7 @@ public:
    return true;
  }

  H5::H5File& open_file(std::string file_name_ref, bool overwrite = true);
  void open_file(std::string file_name_ref, bool overwrite = true);
  void close_file();

  void open_group(std::string new_path);
@@ -58,11 +60,6 @@ public:

  std::string get_path();

  // Closes all open datasets. Overwriting them will no longer be possible.
  void flush() {
    datasets_.clear();
  }

  template <typename arbitrary_struct_t>
  static void to_file(const arbitrary_struct_t& arbitrary_struct, const std::string& file_name);

@@ -133,11 +130,6 @@ public:
    return execute(name, static_cast<io::Buffer::Container>(buffer));
  }

  bool groupExists(const std::string& path) const;

  // Returns -1 if datasets does not exist.
  std::array<hsize_t, 2> datasetId(const std::string& path);

  operator bool() const {
    return static_cast<bool>(file_);
  }
@@ -153,17 +145,16 @@ public:
private:
  bool fexists(const char* filename);

  bool exists(const std::string& name);

  void write(const std::string& name, const std::vector<hsize_t>& size, H5::PredType type,
             const void* data);

  std::unique_ptr<H5::H5File> file_;

  hid_t file_id;
  hid_t file_id_;

  std::unordered_map<std::string, std::unique_ptr<H5::Group>> groups_;
  std::unordered_map<std::string, std::pair<std::unique_ptr<H5::DataSet>, std::unique_ptr<H5::DataSpace>>>
      datasets_;
  std::vector<std::string> my_paths;
  std::vector<std::string> my_paths_;

  bool verbose_;

+77 −32
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@ bool HDF5Writer::fexists(const char* filename) {
  return bool(ifile);
}

H5::H5File& HDF5Writer::open_file(std::string file_name, bool overwrite) {
void HDF5Writer::open_file(std::string file_name, bool overwrite) {
  if (file_)
    throw std::logic_error(__FUNCTION__);

@@ -43,41 +43,34 @@ H5::H5File& HDF5Writer::open_file(std::string file_name, bool overwrite) {
      file_ = std::make_unique<H5::H5File>(file_name.c_str(), H5F_ACC_EXCL);
  }

  file_id = file_->getId();

  if (file_id < 0)
    throw std::runtime_error("Cannot open file : " + file_name);

  return (*file_);
  file_id_ = file_->getId();
}

void HDF5Writer::close_file() {
  datasets_.clear();
  groups_.clear();
  file_->close();
  file_.release();
}

void HDF5Writer::open_group(std::string name) {
  my_paths.push_back(name);
  my_paths_.push_back(name);
  const std::string path = get_path();

  if (!groupExists(path)) {
    groups_[path] = std::make_unique<H5::Group>(file_->createGroup(path.c_str()));
  if (!exists(path)) {
    file_->createGroup(path.c_str());
  }
}

void HDF5Writer::close_group() {
  my_paths.pop_back();
  my_paths_.pop_back();
}

std::string HDF5Writer::get_path() {
  std::string path = "/";

  for (size_t i = 0; i < my_paths.size(); i++) {
    path += my_paths[i];
  for (size_t i = 0; i < my_paths_.size(); i++) {
    path += my_paths_[i];

    if (i < my_paths.size() - 1)
    if (i < my_paths_.size() - 1)
      path += "/";
  }

@@ -87,45 +80,97 @@ std::string HDF5Writer::get_path() {
void HDF5Writer::execute(const std::string& name,
                         const std::string& value)  //, H5File& file, std::string path)
{
  std::string full_name = get_path() + '/' + name;
  if (value.size() > 0) {
    H5::H5File& file = (*file_);
    std::string path = get_path();

    hsize_t dims[1];

    H5::DataSet* dataset = NULL;
    H5::DataSpace* dataspace = NULL;

    {
      dims[0] = value.size();
      dataspace = new H5::DataSpace(1, dims);

  write(full_name, std::vector<hsize_t>{value.size()}, HDF5_TYPE<char>::get_PredType(), value.data());
      std::string full_name = path + "/" + name;
      dataset = new H5::DataSet(
          file.createDataSet(full_name.c_str(), HDF5_TYPE<char>::get_PredType(), *dataspace));

      H5Dwrite(dataset->getId(), HDF5_TYPE<char>::get(), dataspace->getId(), H5S_ALL, H5P_DEFAULT,
               &value[0]);
    }

    delete dataset;
    delete dataspace;
  }
}

void HDF5Writer::execute(const std::string& name,
                         const std::vector<std::string>& value)  //, H5File& file, std::string path)
{
  if (value.size() > 0) {
    H5::H5File& file = (*file_);

    open_group(name);
    execute("size", value.size());

    execute("size", value.size());  //, file, new_path);

    open_group("data");

    const auto path = get_path();
    hsize_t dims[1];

    H5::DataSet* dataset = NULL;
    H5::DataSpace* dataspace = NULL;

    for (int i = 0; i < value.size(); ++i) {
      execute(get_path() + "/" + std::to_string(i), value[i]);
    for (size_t l = 0; l < value.size(); l++) {
      dims[0] = value[l].size();
      dataspace = new H5::DataSpace(1, dims);

      std::stringstream ss;
      ss << get_path() << "/" << l;

      dataset = new H5::DataSet(
          file.createDataSet(ss.str().c_str(), HDF5_TYPE<char>::get_PredType(), *dataspace));

      H5Dwrite(dataset->getId(), HDF5_TYPE<char>::get(), dataspace->getId(), H5S_ALL, H5P_DEFAULT,
               &(value[l][0]));
    }

    close_group();

    delete dataset;
    delete dataspace;

    close_group();
  }
}

bool HDF5Writer::groupExists(const std::string& path) const {
  return groups_.count(path);
}

void HDF5Writer::write(const std::string& name, const std::vector<hsize_t>& dims, H5::PredType type,
                       const void* data) {
  if (datasets_.count(name) == 0) {
    datasets_[name].second = std::make_unique<H5::DataSpace>(dims.size(), dims.data());
    datasets_[name].first = std::make_unique<H5::DataSet>(
        file_->createDataSet(name.c_str(), type, *datasets_[name].second));
  if (exists(name)) {
    H5::DataSet dataset = file_->openDataSet(name.c_str());
    H5::DataSpace dataspace = dataset.getSpace();

#ifndef NDEBUG  // Check for a size match.
    std::vector<hsize_t> size_check(dims.size());
    dataspace.getSimpleExtentDims(size_check.data(), nullptr);
    assert(dims == size_check);
#endif

    dataset.write(data, type, dataspace, H5P_DEFAULT);
  }
  else {
    H5::DataSpace dataspace(dims.size(), dims.data());
    H5::DataSet dataset(file_->createDataSet(name.c_str(), type, dataspace));

    dataset.write(data, type, dataspace, H5P_DEFAULT);
  }
}
  // TODO: check pre-existing size

  datasets_[name].first->write(data, type, *datasets_[name].second, H5P_DEFAULT);
bool HDF5Writer::exists(const std::string& name) {
  auto code = H5Gget_objinfo(file_id_, name.c_str(), 0, NULL);
  return code == 0;
}

}  // namespace io
+2 −3
Original line number Diff line number Diff line
@@ -239,9 +239,8 @@ TEST(HDF5ReaderWriterTest, Overwrite) {
  writer.execute("a", 1);
  writer.execute("a", 2);

  writer.flush();
  H5::Exception::dontPrint();
  EXPECT_THROW(writer.execute("a", 3), H5::Exception);
  // Try to write with different size.
  EXPECT_DEBUG_DEATH(writer.execute("a", std::pair<int, int>(1, 1)), "");

  writer.close_file();