Commit 02bc73e6 authored by gbalduzz's avatar gbalduzz
Browse files

Use HDf5::openDataSet instead of manually tracking existing datasets.

parent c181e1a4
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_;

+27 −30
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 += "/";
  }

@@ -153,27 +146,31 @@ void HDF5Writer::execute(const std::string& name,
  }
}

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
  else {  // Check for a size match.
#ifndef NDEBUG  // Check for a size match.
    std::vector<hsize_t> size_check(dims.size());
    datasets_[name].second->getSimpleExtentDims(size_check.data(), nullptr);
    dataspace.getSimpleExtentDims(size_check.data(), nullptr);
    assert(dims == size_check);
  }
#endif

  datasets_[name].first->write(data, type, *datasets_[name].second, H5P_DEFAULT);
    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);
  }
}

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();