#include "swppfdtable.h" #include "sopnamsp.h" #include "pexceptions.h" /*! \class SOPHYA::SwPPFDataTable \ingroup HiStats This class can be used to organize data in table (row-column) form. Each column holds homogeneous data (same data type), while different columns can be used for different data types (integer, float, string ...) \sa SOPHYA::MuTyV \sa SOPHYA::BaseDataTable \sa SOPHYA::ObjFileIO \code #include "swppfdtable.h" // ... DataTable dt(64); dt.AddFloatColumn("X0_f"); dt.AddFloatColumn("X1_f"); dt.AddDoubleColumn("X0X0pX1X1_d"); double x[5]; for(int i=0; i<63; i++) { x[0] = (i%9)-4.; x[1] = (i/9)-3.; x[2] = x[0]*x[0]+x[1]*x[1]; dt.AddLine(x); } // Printing table info cout << dt ; // Saving object into a PPF file POutPersist po("dtable.ppf"); po << dt ; \endcode */ /*! Default constructor with optional specification of block (or segment) size - NOT intented for general use */ SwPPFDataTable::SwPPFDataTable(sa_size_t segsz) : BaseDataTable(segsz), mSwOut(NULL), mSwIn(NULL) { } /*! Constructor with the specification of the output swap stream - and optional specification of block (or segment) size */ SwPPFDataTable::SwPPFDataTable(POutPersist & os, sa_size_t segsz) : BaseDataTable(segsz) , mISwapper(os), mLSwapper(os), mFSwapper(os), mDSwapper(os), mSSwapper(os), mSwOut(&os), mSwIn(NULL) { } //! Protected constructor for creation from a swap stream SwPPFDataTable::SwPPFDataTable(PInPersist & is, sa_size_t segsz) : BaseDataTable(segsz) , mISwapper(is), mLSwapper(is), mFSwapper(is), mDSwapper(is), mSSwapper(is), mSwOut(NULL), mSwIn(&is) { } //! copy constructor - shares the data SwPPFDataTable::SwPPFDataTable(SwPPFDataTable const & a) : BaseDataTable(a.SegmentSize()), mSwOut(NULL), mSwIn(NULL) { Share(a); } void SwPPFDataTable::Share(SwPPFDataTable const & a) { // Recopie (attention !) brutale des swappers et les streams associes mISwapper = a.mISwapper; mLSwapper = a.mLSwapper; mFSwapper = a.mFSwapper; mDSwapper = a.mDSwapper; mSSwapper = a.mSSwapper; mSwOut = a.mSwOut; mSwIn = a.mSwIn; // On recopie la taille de segment mSegSz = a.SegmentSize(); if (a.NVar() == 0) return; // Table sans colonne // On copie la structure de table CopyStructure(a); // // Update nombre d'entree, ... mNEnt = a.mNEnt; mNSeg = a.mNSeg; if (a.mInfo) mInfo = new DVList(*(a.mInfo)); // mis a jour des tableax min-max mMin = a.mMin; mMax = a.mMax; mMinMaxNEnt = a.mMinMaxNEnt; // Et on partage les donnees des colonnes for (size_t kk=0; kk 0) throw ParmError("SwPPFDataTable::AddColumn() Table contains already data "); CheckColName(cnom); sa_size_t ser; sa_size_t idx = NVar(); switch (ft) { case IntegerField : ser = mICols.size(); mICols.push_back(SwSegDataBlock(mISwapper, mSegSz)); mIColIdx.push_back(idx); mIColsP.push_back(NULL); for(sa_size_t kk=0; kk(mLSwapper, mSegSz)); mLColIdx.push_back(idx); mLColsP.push_back(NULL); for(sa_size_t kk=0; kk(mFSwapper, mSegSz)); mFColIdx.push_back(idx); mFColsP.push_back(NULL); for(sa_size_t kk=0; kk( mDSwapper,mSegSz)); mDColIdx.push_back(idx); mDColsP.push_back(NULL); for(sa_size_t kk=0; kk(mSSwapper, mSegSz)); mSColIdx.push_back(idx); mSColsP.push_back(NULL); for(sa_size_t kk=0; kk mMax[k]) mMax[k] = x; mMinMaxNEnt[k]++; } return BaseDataTable::AddLine(data); } sa_size_t SwPPFDataTable::AddLine(const MuTyV * data) { // On est oblige de calculer les min-max lors du remplissage // On ne peut pas en effet 'relire' le swap pendant l'ecriture for(sa_size_t k=0; k mMax[k]) mMax[k] = x; mMinMaxNEnt[k]++; } return BaseDataTable::AddLine(data); } /*! \class SOPHYA::ObjFileIO \ingroup HiStats Persistence (serialisation) handler for class SwPPFDataTable */ /* --Methode-- */ DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */ void ObjFileIO::WriteSelf(POutPersist& s) const // Serialisation en ecriture du SwPPFDataTable sur stream PPF { if (dobj == NULL) throw NullPtrError("ObjFileIO::WriteSelf() NULL dobj pointer "); if (dobj->mSwOut != &s) throw NotAvailableOperation("ObjFileIO::WriteSelf() OutputStream <> SwapStream"); //------- On ecrit 3 uint_4 .... // [0]: Numero de version ; // [1] : bit1 non nul -> has info // [2] : reserve uint_4 itab[3]; itab[0] = 1; // Numero de version a 1 itab[1] = itab[2] = 0; if (dobj->mInfo) itab[1] = 1; s.Put(itab, 3); //-------- Ecriture de segment size, nb de colonnes, nb de lignes ... // [0] : SegmentSize() [1] : NVar() // [2] : NEntry() [3] : NbSegments() uint_8 ltab[5]; ltab[0] = dobj->SegmentSize(); ltab[1] = dobj->NVar(); ltab[2] = dobj->NEntry(); ltab[3] = dobj->NbSegments(); ltab[4] = 0; s.Put(ltab, 5); //------ Ecriture du nom et type des colonnes for(sa_size_t k=0; kNVar(); k++) { uint_2 typ = dobj->mNames[k].type; s.Put(typ); s.Put(dobj->mNames[k].nom); } // ------- Ecriture des tableaux min,max et n_minmax for(uint_8 k=0; kmMin[k]); s.Put(dobj->mMax[k]); s.Put(dobj->mMinMaxNEnt[k]); } //------- Ecriture du DVList Info() associe, si existant if (dobj->mInfo) s << (*(dobj->mInfo)); //------- Ecriture des tables de positionnement de SwSegDataBlock for (size_t kk=0; kkmNames.size(); kk++) { sa_size_t sk = dobj->mNames[kk].ser; switch (dobj->mNames[kk].type) { case BaseDataTable::IntegerField : s.PutPosTagTable(dobj->mICols[sk].GetSwapPosTagTable()); break; case BaseDataTable::LongField : s.PutPosTagTable(dobj->mLCols[sk].GetSwapPosTagTable()); break; case BaseDataTable::FloatField : s.PutPosTagTable(dobj->mFCols[sk].GetSwapPosTagTable()); break; case BaseDataTable::DoubleField : s.PutPosTagTable(dobj->mDCols[sk].GetSwapPosTagTable()); break; case BaseDataTable::StringField : s.PutPosTagTable(dobj->mSCols[sk].GetSwapPosTagTable()); break; default: throw ForbiddenError("ObjFileIO::WriteSelf() : unknown column type "); break; } } return; } /* --Methode-- */ DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */ void ObjFileIO::ReadSelf(PInPersist& s) // Serialisation en lecture du SwPPFDataTable sur stream PPF { // ------- On lit les 3 premiers uint_4 // [0]: Numero de version ; // [1] : bit1 non nul -> has info // [2] : reserve uint_4 itab[3] = {0,0,0}; s.Get(itab, 3); bool hadinfo = false; if ((itab[1]&1) == 1) hadinfo = true; // -------- Lecture de segment size, nb de colonnes, nb de lignes ... // [0] : SegmentSize() [1] : NVar() // [2] : NEntry() [3] : NbSegments() uint_8 ltab[5] = {0,0,0,0,0}; s.Get(ltab, 5); if (dobj == NULL) dobj = new SwPPFDataTable(s, ltab[0]); else { // Copie brutale en utilisant l'operateur = *dobj = SwPPFDataTable(s, ltab[0]); } // -------- Lecture nom/type colonnes et allocation des colonnes uint_2 typ; string cnom; for(uint_8 k=0; kAddColumn(ft, cnom); } // ------- Lecture des tableaux min,max et n_minmax for(uint_8 k=0; kmMin[k]); s.Get(dobj->mMax[k]); s.Get(dobj->mMinMaxNEnt[k]); } // ------- Lecture du DVList Info() associe, si necessaire if (hadinfo) { // Lecture eventuelle du DVList Info if (dobj->mInfo == NULL) dobj->mInfo = new DVList; s >> (*(dobj->mInfo)); } // ------- Mise a jour des champs Nb d'entrees, nb segments ... dobj->mNEnt = ltab[2]; dobj->mNSeg = ltab[3]; cout << " DEBUG___ SegmentSize()= " << dobj->SegmentSize() << endl; // ------- Lecture des tag de positionnement des SwSegDataBlock vector swpos; for (size_t kk=0; kkmNames.size(); kk++) { sa_size_t sk = dobj->mNames[kk].ser; switch (dobj->mNames[kk].type) { case BaseDataTable::IntegerField : swpos.clear(); s.GetPosTagTable(swpos); dobj->mICols[sk] = SwSegDataBlock(dobj->mISwapper, swpos, dobj->SegmentSize()); break; case BaseDataTable::LongField : swpos.clear(); s.GetPosTagTable(swpos); dobj->mLCols[sk] = SwSegDataBlock(dobj->mLSwapper, swpos, dobj->SegmentSize()); break; case BaseDataTable::FloatField : swpos.clear(); s.GetPosTagTable(swpos); dobj->mFCols[sk] = SwSegDataBlock(dobj->mFSwapper, swpos, dobj->SegmentSize()); break; case BaseDataTable::DoubleField : swpos.clear(); s.GetPosTagTable(swpos); dobj->mDCols[sk] = SwSegDataBlock(dobj->mDSwapper, swpos, dobj->SegmentSize()); break; case BaseDataTable::StringField : swpos.clear(); s.GetPosTagTable(swpos); dobj->mSCols[sk] = SwSegDataBlock(dobj->mSSwapper, swpos, dobj->SegmentSize()); break; default: throw ForbiddenError("ObjFileIO::ReadSelf() : unknown column type "); break; } } return; } #ifdef __CXX_PRAGMA_TEMPLATES__ #pragma define_template ObjFileIO #endif #if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES) template class ObjFileIO; #endif