ranges: extend + array: init + extend + hdf5: adapt

This commit is contained in:
Christian Zimmermann 2023-01-18 00:49:11 +01:00
parent d72bf23049
commit e6da712482
19 changed files with 210 additions and 124 deletions

View file

@ -25,6 +25,29 @@ namespace CNORXZ
ArrayBase<T>(range), mCont(vec)
{}
template <typename T>
MArray<T>& MArray<T>::init(const RangePtr& range)
{
AB::mRange = rangeCast<YRange>(range);
mCont.resize(AB::mRange->size());
return *this;
}
template <typename T>
MArray<T>& MArray<T>::extend(const RangePtr& range)
{
MArray<T> tmp(AB::mRange->extend(range));
auto ei = this->end();
auto ti = tmp.begin();
// this is not very efficient; remove by sub-index operation once available:
for(auto ii = this->begin(); ii != ei; ++ii){
ti.at(ii.meta());
*ti = *ii;
}
*this = std::move(tmp);
return *this;
}
template <typename T>
const T* MArray<T>::data() const
{

View file

@ -21,6 +21,8 @@ namespace CNORXZ
MArray(const RangePtr& range);
MArray(const RangePtr& range, const Vector<T>& vec);
MArray(const RangePtr& range, Vector<T>&& vec);
MArray& init(const RangePtr& range);
MArray& extend(const RangePtr& range);
virtual const T* data() const override;
virtual T* data() override;

View file

@ -88,6 +88,7 @@ namespace CNORXZ
virtual String stringMeta(SizeT pos) const override final;
virtual const TypeInfo& type() const override final;
virtual const TypeInfo& metaType() const override final;
virtual RangePtr extend(const RangePtr& r) const override final;
SizeT get(SizeT pos) const;
SizeT getMeta(SizeT metaPos) const;

View file

@ -594,6 +594,19 @@ namespace CNORXZ
return i.at(metaPos).pos();
}
template <class... Ranges>
RangePtr MRange<Ranges...>::extend(const RangePtr& r) const
{
CXZ_ASSERT( r->dim() == this->dim(), "cannot extend range of dimension "
<< this->dim() << " by range of dimension " << r->dim());
auto rs = iter<0,NR>( [&](auto i) {
typedef typename std::remove_reference<decltype(*std::get<i>(mRs))>::type RType;
return std::dynamic_pointer_cast<RType>( std::get<i>(mRs)->extend(r->sub(i)) ); },
[](const auto&... e) { return std::make_tuple(e...); }
);
return MRangeFactory<Ranges...>( rs ).create();
}
/************************
* MRange (private) *
************************/

View file

@ -179,6 +179,7 @@ namespace CNORXZ
virtual String stringMeta(SizeT pos) const override final;
virtual const TypeInfo& type() const override final;
virtual const TypeInfo& metaType() const override final;
virtual RangePtr extend(const RangePtr& r) const override final;
decltype(auto) space() const;
const MetaType get(SizeT pos) const;

View file

@ -53,6 +53,7 @@ namespace CNORXZ
virtual const TypeInfo& metaType() const = 0;
virtual String stringMeta(SizeT pos) const = 0;
virtual DIndex index(SizeT pos = 0) const = 0;
virtual RangePtr extend(const RangePtr& r) const = 0;
bool operator==(const RangeBase& in) const;
bool operator!=(const RangeBase& in) const;

View file

@ -273,6 +273,15 @@ namespace CNORXZ
return typeid(MetaType);
}
template <typename MetaType>
RangePtr URange<MetaType>::extend(const RangePtr& r) const
{
auto rx = rangeCast<URange<MetaType>>(r);
auto space = mSpace;
space.insert(space.end(), rx->mSpace.begin(), rx->mSpace.end());
return URangeFactory<MetaType>( space ).create();
}
/*******************
* Range Casts *
*******************/

View file

@ -95,6 +95,7 @@ namespace CNORXZ
virtual String stringMeta(SizeT pos) const override final;
virtual const TypeInfo& type() const override final;
virtual const TypeInfo& metaType() const override final;
virtual RangePtr extend(const RangePtr& r) const override final;
const MetaType& get(SizeT pos) const;
SizeT getMeta(const MetaType& metaPos) const;

View file

@ -216,6 +216,18 @@ namespace CNORXZ
return DXpr<SizeT>(mI->ifor(xpr, std::forward<std::function<SizeT(SizeT,SizeT)>>(f)));
}
template <class Index, typename Meta>
Index& XIndex<Index,Meta>::get()
{
return mI->THIS();
}
template <class Index, typename Meta>
const Index& XIndex<Index,Meta>::get() const
{
return mI->THIS();
}
template <class Index>
inline XIndexPtr xindexPtr(const Sptr<Index>& i)
{

View file

@ -101,6 +101,9 @@ namespace CNORXZ
virtual DXpr<SizeT> ifor(const DXpr<SizeT>& xpr,
std::function<SizeT(SizeT,SizeT)>&& f) const override final;
Index& get();
const Index& get() const;
private:
IndexPtr<Index,Meta> mI;

View file

@ -123,6 +123,7 @@ namespace CNORXZ
virtual String stringMeta(SizeT pos) const override final;
virtual const TypeInfo& type() const override final;
virtual const TypeInfo& metaType() const override final;
virtual RangePtr extend(const RangePtr& r) const override final;
private:

View file

@ -172,6 +172,12 @@ namespace CNORXZ
return typeid(SizeT);
}
RangePtr CRange::extend(const RangePtr& r) const
{
auto rx = rangeCast<CRange>(r);
return CRangeFactory( this->size() + rx->size() ).create();
}
/*******************
* Range Casts *
*******************/

View file

@ -484,6 +484,17 @@ namespace CNORXZ
return typeid(DType);
}
RangePtr YRange::extend(const RangePtr& r) const
{
CXZ_ASSERT(r->dim() == this->dim(), "cannot extend range of dimension "
<< this->dim() << " by range of dimension " << r->dim());
Vector<RangePtr> rvec(this->dim());
for(SizeT i = 0; i != this->dim(); ++i){
rvec[i] = mRVec[i]->extend( r->sub(i) );
}
return YRangeFactory( rvec ).create();
}
YRange::YRange(const Vector<RangePtr>& rvec) : mRVec(rvec) {}
YRange::YRange(Vector<RangePtr>&& rvec) : mRVec(std::forward<Vector<RangePtr>>(rvec)) {}

View file

@ -27,11 +27,9 @@ namespace CNORXZ
virtual ContentType type() const = 0;
virtual bool ro() const = 0;
virtual ContentBase& load() = 0;
virtual ContentBase& open() = 0;
virtual ContentBase& write() = 0;
virtual ContentBase& close() = 0;
virtual MArray<Sptr<ContentBase>>* get() = 0;
virtual const MArray<Sptr<ContentBase>>* get() const = 0;
virtual String path() const = 0;
virtual String filename() const = 0;
@ -39,6 +37,7 @@ namespace CNORXZ
const ContentBase* parent() const;
RangePtr range() const;
hid_t id() const;
inline bool isOpen() const { return mId != 0; }
protected:
String mName;

View file

@ -3,14 +3,15 @@
#define __cxz_h5_file_h__
#include "h5_content_base.h"
#include <hdf5.h>
#include "h5_group.h"
//#include <hdf5.h>
namespace CNORXZ
{
namespace hdf5
{
// maybe introduce abstraction layer between as base for File and Group
class File : public ContentBase
class File : public Group
{
public:
typedef URange<String> RangeT;
@ -21,21 +22,16 @@ namespace CNORXZ
virtual ContentType type() const override final;
virtual bool ro() const override final;
virtual File& load() override final;
virtual File& open() override final;
virtual File& write() override final;
virtual File& close() override final;
virtual MArray<Sptr<ContentBase>>* get() override final;
virtual const MArray<Sptr<ContentBase>>* get() const override final;
virtual String path() const override final;
virtual String filename() const override final;
Int exists() const;
File& set(const RangePtr& range);
File& append(const String& cname);
virtual Int exists() const override final;
private:
bool mRo = true;
MArray<ContentPtr> mCont;
};
}
}

View file

@ -15,21 +15,26 @@ namespace CNORXZ
Group(const String& gname, const ContentBase* _parent);
~Group();
virtual ContentType type() const override final;
virtual bool ro() const override final;
virtual Group& load() override final;
virtual Group& write() override final;
virtual Group& close() override final;
virtual MArray<Sptr<ContentBase>>* get() override final;
virtual const MArray<Sptr<ContentBase>>* get() const override final;
virtual String path() const override final;
virtual String filename() const override final;
virtual ContentType type() const override;
virtual bool ro() const override;
virtual Group& open() override; // load group if existing, else create new group
virtual Group& write() override;
virtual Group& close() override;
virtual String path() const override;
virtual String filename() const override;
bool exists() const;
Group& append(const ContentPtr& c);
virtual Int exists() const;
private:
const MArray<ContentPtr>& get() const;
Group& addGroup(const String& name);
template <typename T>
Group& addData(const String& name, const ArrayBase<T>& data);
protected:
MArray<ContentPtr> mCont;
void mkCont();
};
}

View file

@ -7,8 +7,26 @@ namespace CNORXZ
namespace hdf5
{
File::File(const String& fname, bool _ro) :
ContentBase(fname),
Group(fname, nullptr),
mRo(_ro)
{}
File::~File()
{
this->close();
}
ContentType File::type() const
{
return ContentType::FILE;
}
bool File::ro() const
{
return mRo;
}
File& File::open()
{
Int ex = this->exists();
const String fn = this->filename();
@ -27,27 +45,7 @@ namespace CNORXZ
}
}
CXZ_ASSERT( mId > 0, "error while opening file '" << fn << "'" );
}
File::~File()
{
this->close();
}
ContentType File::type() const
{
return ContentType::FILE;
}
bool File::ro() const
{
return mRo;
}
File& File::load()
{
// !!!
this->mkCont();
return *this;
}
@ -75,16 +73,6 @@ namespace CNORXZ
return *this;
}
MArray<Sptr<ContentBase>>* File::get()
{
return &mCont;
}
const MArray<Sptr<ContentBase>>* File::get() const
{
return &mCont;
}
String File::path() const
{
return String("/");
@ -111,41 +99,5 @@ namespace CNORXZ
return ex;
}
File& File::set(const RangePtr& range)
{
if(mCont.range() != nullptr){
CXZ_ERROR("IMPLEMENT");
// operator+ for RangePtr!!!
}
else {
mCont = MArray<ContentPtr>(range);
}
return *this;
}
File& File::append(const String& cname)
{
if(mCont.range() != nullptr){
auto oldrange = std::dynamic_pointer_cast<URange<String>>(mCont.range());
Vector<String> names(oldrange->size());
for(auto i = oldrange->begin(); i != oldrange->end(); ++i){
names[i.lex()] = *i;
}
names[names.size()-1] = cname;
auto range = URangeFactory<String>( names ).create();
MArray<ContentPtr> ncont( range );
auto j = ncont.begin();
for(auto i = mCont.begin(); i != mCont.end(); ++i){
j.at( i.meta() );
ncont[j] = mCont[i];
}
mCont = ncont;
}
else {
auto range = URangeFactory<String>( Vector<String>({cname}) ).create();
mCont = MArray<ContentPtr>( range );
}
return *this;
}
}
}

View file

@ -7,21 +7,11 @@ namespace CNORXZ
{
Group::Group(const String& gname, const ContentBase* _parent) :
ContentBase(gname, _parent)
{
if(this->exists()){
mId = H5Gopen( mParent->id(), mName.c_str(), H5P_DEFAULT );
}
else {
mId = H5Gcreate( mParent->id(), mName.c_str(),
H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT );
}
}
{}
Group::~Group()
{
if(mId != 0){
H5Gclose(mId);
}
this->close();
}
ContentType Group::type() const
@ -37,9 +27,16 @@ namespace CNORXZ
return false;
}
Group& Group::load()
Group& Group::open()
{
// load content!!!
if(this->exists()){
mId = H5Gopen( mParent->id(), mName.c_str(), H5P_DEFAULT );
}
else {
mId = H5Gcreate( mParent->id(), mName.c_str(),
H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT );
}
this->mkCont();
return *this;
}
@ -51,19 +48,12 @@ namespace CNORXZ
Group& Group::close()
{
if(mId != 0){
H5Gclose(mId);
}
return *this;
}
MArray<Sptr<ContentBase>>* Group::get()
{
return &mCont;
}
const MArray<Sptr<ContentBase>>* Group::get() const
{
return &mCont;
}
String Group::path() const
{
if(mParent){
@ -80,15 +70,67 @@ namespace CNORXZ
return String();
}
bool Group::exists() const
Int Group::exists() const
{
return H5Lexists(mParent->id(), mName.c_str(), H5P_DEFAULT) != 0;
return H5Lexists(mParent->id(), mName.c_str(), H5P_DEFAULT) != 0 ? 1 : 0;
}
Group& Group::append(const ContentPtr& c)
const MArray<ContentPtr>& Group::get() const
{
return mCont;
}
return *this;
struct InitContData
{
const ContentBase* parent;
BIndex<ContentPtr> index;
};
static herr_t addName(hid_t id, const char* name, const H5L_info_t* info, void* x)
{
Vector<String>* names = reinterpret_cast<Vector<String>*>(x);
names->push_back(String(name));
return 0;
}
static herr_t initCont(hid_t id, const char* name, const H5L_info_t* info, void* x)
{
const String sname(name);
InitContData* icd = reinterpret_cast<InitContData*>(x);
BIndex<ContentPtr>& index = icd->index;
UIndex<String>& ui = std::dynamic_pointer_cast<XIndex<UIndex<String>,String>>
(index.pack()[0])->get();
ui.at(sname);
index();
H5O_info_t oinfo;
H5Oget_info(id, &oinfo, H5O_INFO_BASIC);
switch (oinfo.type) {
case H5O_TYPE_GROUP: {
*index = std::make_shared<Group>(sname, icd->parent);
break;
}/*
case H5O_TYPE_DATASET: {
*index = std::make_shared<DSet>(sname, );
break;
}*/
default:
return 1;
}
return 0;
}
void Group::mkCont()
{
Vector<String> names;
H5Literate( mId, H5_INDEX_NAME, H5_ITER_NATIVE, NULL,
addName, reinterpret_cast<void*>(&names) );
mCont.init( URangeFactory<String>( names ).create() );
InitContData icd;
icd.index = mCont.begin();
icd.parent = this;
H5Literate( mId, H5_INDEX_NAME, H5_ITER_NATIVE, NULL,
initCont, reinterpret_cast<void*>(&icd) );
}
}

View file

@ -2,7 +2,7 @@
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <filesystem>
#include <cstdio>
#include "gtest/gtest.h"
@ -12,7 +12,6 @@ namespace
{
using namespace CNORXZ;
using namespace CNORXZ::hdf5;
namespace sfs = std::filesystem;
class NoFile_Test : public ::testing::Test
{
@ -38,10 +37,12 @@ namespace
Group_Test()
{
mFileName = "test_file.h5";
sfs::remove(mFileName);
std::remove(mFileName.c_str());
mGrps = { "gr1", "gr2" };
}
String mFileName;
Vector<String> mGrps;
};
TEST_F(NoFile_Test, NoFile)
@ -63,12 +64,19 @@ namespace
File h5f(mFileName, false);
EXPECT_FALSE(h5f.ro());
//h5f.append("gr1");
auto grange = URangeFactory<String>( Vector<String>( { "gr1", "gr2" } ) ).create();
auto grange = URangeFactory<String>( mGrps ).create();
h5f.set( grange );
for(auto i = grange->begin(); i != grange->end(); ++i){
(*h5f.get())[i] = std::make_shared<Group>( i.meta().str(), &h5f );
}
}
TEST_F(Group_Test, Read)
{
File h5f(mFileName, true);
EXPECT_TRUE(h5f.ro());
}
}
// check write to new file