WIP: more development on h5_table

This commit is contained in:
Christian Zimmermann 2023-01-23 19:22:42 +01:00
parent 59932895e9
commit 0db94229bf
6 changed files with 108 additions and 83 deletions

View file

@ -0,0 +1,29 @@
#ifndef __cxz_h5_group_cc_h__
#define __cxz_h5_group_cc_h__
namespace CNORXZ
{
namespace hdf5
{
template <typename T>
Group& Group::addData(const String& name, const ArrayBase<T>& data)
{
CXZ_ASSERT(this->isOpen(), "tried to extend closed group");
CXZ_ERROR("not implemented!!!");
return *this;
}
template <typename... Ts>
Group& Group::addTable(const String& name, const ArrayBase<Tuple<Ts...>>& data,
const RangePtr& fields)
{
CXZ_ASSERT(this->isOpen(), "tried to extend closed group");
return *this;
}
}
}
#endif

View file

@ -30,6 +30,10 @@ namespace CNORXZ
template <typename T> template <typename T>
Group& addData(const String& name, const ArrayBase<T>& data); Group& addData(const String& name, const ArrayBase<T>& data);
template <typename... Ts>
Group& addTable(const String& name, const ArrayBase<Tuple<Ts...>>& data,
const RangePtr& fields);
protected: protected:
MArray<ContentPtr> mCont; MArray<ContentPtr> mCont;

View file

@ -16,49 +16,54 @@ namespace CNORXZ
} }
template <typename... Ts> template <typename... Ts>
STabel<Ts...>::STabel(const String& name, const ContentBase* _parent) : STabel<Ts...>::STabel(const String& name, const ContentBase* _parent, const RangePtr& fields) :
Table(name, _parent) Table(name, _parent)
{ {
// checks..!!!! constexpr SizeT N = sizeof...(Ts);
if(mFields == nullptr){
CXZ_ASSERT(fields != nullptr, "field names have to be initialized");
mFields = fields;
}
CXZ_ASSERT(mFields->size() == sizeof...(Ts), "expected tuple of size = " << mFields->size()
<< ", got: " << sizeof...(Ts));
if(mRecords == nullptr) {
auto mOffsets = MArray<SizeT>( mFields, iter<0,N>
( [&](auto i) { return &std::get<i>(t) - &t; },
[](const auto&... e) { return Vector<SizeT>({e...}); }) );
auto mSizes = MArray<SizeT>( mFields, iter<0,N>
( [&](auto i) { return sizeof(std::get<i>(t)); },
[](const auto&... e) { return Vector<SizeT>({e...}); }) );
auto mTypes = MArray<hid_t>( mFields, iter<0,N>
( [&](auto i) { return getTypeId(std::get<i>(t)); },
[](const auto&... e) { return Vector<hid_t>({e...}); }) );
}
else {
iter<0,N>( [&](auto i) { CXZ_ASSERT
( &std::get<i>(t) - &t == mOffsets.data()[i],
"wrong offset for field " << i << ": " << &std::get<i>(t) - &t
<< " vs " << mOffsets.data()[i] ); }, NoF{} );
iter<0,N>( [&](auto i) { CXZ_ASSERT
( sizeof(std::get<i>(t)) == mSizes.data()[i],
"wrong size for field " << i << ": " << sizeof(std::get<i>(t))
<< " vs " << mSizes.data()[i] ); }, NoF{} );
iter<0,N>( [&](auto i) { CXZ_ASSERT
( getTypeId(std::get<i>(t)) == mTypes.data()[i],
"wrong type for field " << i << ": " << getTypeId(std::get<i>(t))
<< " vs " << mTypes.data()[i] ); }, NoF{} );
}
} }
template <typename... Ts> template <typename... Ts>
STabel& STabel<Ts...>::appendRecord(const Tuple<Ts...>& t) STabel& STabel<Ts...>::appendRecord(const Tuple<Ts...>& t)
{ {
if(not mCheckedFile){
this->open();
}
this->close(); // H5TB does not require an open dataset
CXZ_ASSERT(mFields != nullptr,
"field names have to be initialized before creating table");
CXZ_ASSERT(mFields->size() == sizeof...(Ts),
"expected tuple of size = " << mFields->size()
<< ", got: " << sizeof...(Ts));
RangePtr appr = CRangeFactory(1).create(); RangePtr appr = CRangeFactory(1).create();
auto offsets = iter<0,sizeof...(Ts)>
( [&](auto i) { return &std::get<i>(t) - &t; },
[](const auto&... e) { return Vector<SizeT>({e...}); });
auto sizes = iter<0,sizeof...(Ts)>
( [&](auto i) { return sizeof(std::get<i>(t)); },
[](const auto&... e) { return Vector<SizeT>({e...}); });
auto types = iter<0,sizeof...(Ts)>
( [&](auto i) { return getTypeId(std::get<i>(t)); },
[](const auto&... e) { return Vector<hid_t>({e...}); });
if(mRecords == nullptr){ if(mRecords == nullptr){
mRecords = appr; mRecords = appr;
mSizes = MArray<SizeT>(std::move(sizes));
mOffsets = MArray<SizeT>(std::move(offsets));
mTypes = MArray<hid_t>(std::move(types));
// init
} }
else { else {
// check consistency
mRecords = mRecords->extend(appr); mRecords = mRecords->extend(appr);
} }
// append
H5TBappend_records(mParent->id(), mName, 1, sizeof(t), H5TBappend_records(mParent->id(), mName, 1, sizeof(t),
mOffsets.data(), mSizes.data(), &t); mOffsets.data(), mSizes.data(), &t);
return *this; return *this;

View file

@ -22,12 +22,9 @@ namespace CNORXZ
virtual String path() const override final; virtual String path() const override final;
virtual String filename() const override final; virtual String filename() const override final;
Table& openDSet();
Table& initFieldNames(const Vector<String>& fnames); Table& initFieldNames(const Vector<String>& fnames);
Table& appendRecord(SizeT n, const char* data);
template <class F> Table& readRecord(SizeT pos, SizeT n, char* data);
decltype(auto) iterRecords(F&& f) const;
private: private:
RangePtr mRecords; RangePtr mRecords;
@ -35,7 +32,7 @@ namespace CNORXZ
MArray<SizeT> mSizes; MArray<SizeT> mSizes;
MArray<SizeT> mOffsets; MArray<SizeT> mOffsets;
MArray<hid_t> mTypes; MArray<hid_t> mTypes;
hid_t mType; hid_t mType = 0;
bool mCheckedFile = false; bool mCheckedFile = false;
}; };
@ -44,11 +41,13 @@ namespace CNORXZ
{ {
public: public:
DEFAULT_MEMBERS(STabel); DEFAULT_MEMBERS(STabel);
STabel(const String& name, const ContentBase* _parent); STabel(const String& name, const ContentBase* _parent, const RangePtr& fields);
Table& appendRecord(const Tuple<Ts...>& t); Table& appendRecord(const Tuple<Ts...>& t);
Table& appendRecord(const MArray<Tuple<Ts...>>& t); Table& appendRecord(const MArray<Tuple<Ts...>>& t);
template <class F>
decltype(auto) iterRecords(F&& f) const;
}; };
} }
} }

View file

@ -90,14 +90,6 @@ namespace CNORXZ
return *this; return *this;
} }
template <typename T>
Group& Group::addData(const String& name, const ArrayBase<T>& data)
{
CXZ_ASSERT(this->isOpen(), "tried to extend closed group");
CXZ_ERROR(name << data.size() << " NOT IMPLEMENTED!!!");
return *this;
}
struct InitContData struct InitContData
{ {
const ContentBase* parent; const ContentBase* parent;

View file

@ -8,7 +8,38 @@ namespace CNORXZ
{ {
Table::Table(const String& name, const ContentBase* _parent) : Table::Table(const String& name, const ContentBase* _parent) :
ContentBase(name, _parent) ContentBase(name, _parent)
{} {
if(H5Lexists_by_name(mParent->id(), mName.c_str(), H5P_DEFAULT)){
hsize_t nfields = 0;
hsize_t nrecords = 0;
H5TBget_table_info(mParent->id(), mName.c_str(), &nfields, &nrecords);
mRecords = CRangeFactory( nrecords ).create();
Vector<char*> fieldsptr(nfields);
Vector<SizeT> offsets(nfields);
Vector<SizeT> sizes(nfields);
SizeT typesize = 0;
H5TBget_field_info(mParent->id(), mName.c_str(), fieldsptr.data(), sizes.data(),
offsets.data(), &typesize);
Vector<String> fields(nfields);
for(SizeT i = 0; i != nfields; ++i){
fields[i] = fieldsptr[i];
}
mFields = URangeFactory<String>( std::move(fields) ).create();
mSizes = MArray<SizeT>(mFields, std::move(sizes));
mOffsets = MArray<SizeT>(mFields, std::move(offsets));
this->open();
const SizeT n = H5Tget_nmembers(mType);
CXZ_ASSERT(n == mFields->size(),
"number of dataset members does not match number of fields: "
<< n << " vs " << mFields->size());
Vector<hid_t> types(n);
for(SizeT i = 0; i != n; ++i){
types[i] = H5Tget_member_class( mType, i );
}
mTypes = MArray<hid_t>(mFields, std::move(types));
this->close();
}
}
Table::~Table() Table::~Table()
{ {
@ -27,36 +58,10 @@ namespace CNORXZ
Table& Table::open() Table& Table::open()
{ {
if(H5Oexists_by_name(mParent->id(), mName.c_str(), H5P_DEFAULT)){ if(mId == 0){
hsize_t nfields = 0; mId = H5Dopen(mParent->id(), mName.c_str(), H5P_DEFAULT);
hsize_t nrecords = 0; mType = H5Dget_type(mId);
H5TBget_table_info(mParent->id(), mName.c_str(), &nfields, &nrecords);
mRecords = CRangeFactory( nrecords ).create();
Vector<char*> fieldsptr(nfields);
Vector<SizeT> offsets(nfields);
Vector<SizeT> sizes(nfields);
SizeT typesize = 0;
H5TBget_field_info(mParent->id(), mName.c_str(), fieldsptr.data(), sizes.data(),
offsets.data(), &typesize);
Vector<String> fields(nfields);
for(SizeT i = 0; i != nfields; ++i){
fields[i] = fieldsptr[i];
} }
mFields = URangeFactory<String>( std::move(fields) ).create();
mSizes = MArray<SizeT>(mFields, std::move(sizes));
mOffsets = MArray<SizeT>(mFields, std::move(offsets));
this->openDSet();
const SizeT n = H5Tget_nmembers(mType);
CXZ_ASSERT(n == mFields->size(),
"number of dataset members does not match number of fields: "
<< n << " vs " << mFields->size());
Vector<hid_t> types(n);
for(SizeT i = 0; i != n; ++i){
types[i] = H5Tget_member_class( mType, i );
}
mTypes = MArray<hid_t>(mFields, std::move(types));
}
mCheckedFile = true; // now an empty mRecords etc indicates that there is currently no table at the requested location
return *this; return *this;
} }
@ -79,15 +84,6 @@ namespace CNORXZ
return mParent->filename(); return mParent->filename();
} }
Table& Table::openDSet()
{
if(mId == 0){
mId = H5Dopen(mParent->id(), mName.c_str(), H5P_DEFAULT);
mType = H5Dget_type(mId);
}
return *this;
}
Table& Table::initFieldNames(const Vector<String>& fnames) Table& Table::initFieldNames(const Vector<String>& fnames)
{ {
CXZ_ASSERT(mFields == nullptr, "fields already initialized"); CXZ_ASSERT(mFields == nullptr, "fields already initialized");