Changeset 3392 in Sophya


Ignore:
Timestamp:
Nov 22, 2007, 7:25:40 PM (18 years ago)
Author:
ansari
Message:

Implementation NTuple::Fill(), BaseDataTable:;AddRow()/GetRow() thread-safe - Reza 22/11/2007

Location:
trunk/SophyaLib/HiStats
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/SophyaLib/HiStats/basedtable.cc

    r3181 r3392  
    11#include "basedtable.h"
    22#include <ctype.h>
    3 #include "sopnamsp.h"
    43#include "pexceptions.h"
     4#include "thsafeop.h"
     5
     6namespace SOPHYA {
    57
    68/*!
    7    \class SOPHYA::DataTableRow
     9   \class DataTableRow
    810   \ingroup HiStats
    911   This class is intented to be used with datatable classes
     
    5860
    5961/*!
    60    \class SOPHYA::BaseDataTable
     62   \class BaseDataTable
    6163   \ingroup HiStats
    6264   Base class for data tables. Each line represent a record
    6365   and the column contains a given data type.
     66   \warning
     67   Thread safe fill operation can be activated using the method SetThreadSafe()
     68   Default mode is NON thread-safe fill.   
    6469*/
    6570
     
    147152  mVarMTV = NULL;
    148153  mInfo = NULL;
     154  mThS = NULL;
    149155}
    150156
     
    154160  if (mVarMTV) delete[] mVarMTV;
    155161  if (mInfo) delete mInfo;
    156 }
     162  if (mThS) delete mThS;
     163}
     164
     165/*!
     166  \brief Activate or deactivate thread-safe \b AddRow() operations
     167
     168  If fg==true, create an ThSafeOp object in order to insure atomic AddRow()
     169  and GetRow()/GetColumn() operations. if fg==false, the ThSafeOp object (mThS)
     170  of the target DataTable is destroyed.
     171
     172  When activated, the following operations are thread-safe :
     173
     174  - AddRow(const r_8* data)
     175  - AddRow(const MuTyV* data)
     176  - AddRow(DataTableRow const& data)
     177  - GetRow(sa_size_t n, DataTableRow& row)
     178  - GetRow(sa_size_t n, MuTyV* mtvp)
     179  - GetColumnD(sa_size_t k)
     180
     181  \warning The default AddRow() operation mode for DataTables is NOT thread-safe.
     182  Please note also that the thread-safety state is NOt saved to PPF (or FITS) streams.
     183*/
     184void BaseDataTable::SetThreadSafe(bool fg)
     185{
     186  if (fg) {
     187    if (mThS) return;
     188    else mThS = new ThSafeOp();
     189  }
     190  else {
     191    if (mThS) delete mThS;
     192    mThS = NULL;
     193  }
     194}
     195
     196
     197/*! \cond
     198  \class DT_TSOP_SYNC
     199  \ingroup HiStats
     200  Classe utilitaire pour faciliter la gestion de lock pour
     201  operations thread-safe BaseDataTable
     202*/
     203class DT_TSOP_SYNC {
     204 public:
     205  explicit DT_TSOP_SYNC(ThSafeOp* ths)
     206  {
     207    ths_ = ths;
     208    if (ths_) ths_->lock();
     209  }
     210  ~DT_TSOP_SYNC()
     211  {
     212    if (ths_) ths_->unlock();
     213  }
     214  inline ThSafeOp* NOp() { return ths_; }
     215 protected:
     216  ThSafeOp* ths_;
     217};
     218/*! \endcond */
    157219
    158220sa_size_t BaseDataTable::CopyStructure(BaseDataTable const & a)
     
    273335sa_size_t BaseDataTable::AddRow(const r_8* data)
    274336{
     337  DT_TSOP_SYNC dttss(mThS); dttss.NOp();  // Thread-safe operation
     338
    275339  if (NVar() == 0)
    276340    throw ParmError("BaseDataTable::AddRow(const r_8*) Table has no column !");
     
    309373sa_size_t BaseDataTable::AddRow(const MuTyV* data)
    310374{
     375  DT_TSOP_SYNC dttss(mThS); dttss.NOp();  // Thread-safe operation
     376
    311377  if (NVar() == 0)
    312378    throw ParmError("BaseDataTable::AddRow(const MuTyV*) Table has no column !");
     
    379445  Return a reference to the input \b row object.
    380446  Generate an exception if the input \b row object has the wrong size.
    381   This method is slower(less efficient) than the GetRow(n) method.
    382447*/
    383448DataTableRow& BaseDataTable::GetRow(sa_size_t n, DataTableRow& row) const
     
    385450  if ( row.Size() != NCols() )
    386451    throw SzMismatchError(" BaseDataTable::GetRow(n, row) - row.Size() != NCols() ");
    387   MuTyV* rmtv = GetRow(n);
    388   for(sa_size_t k=0; k<NCols(); k++)
    389     row[k] = rmtv[k];
     452  GetRow(n, row.MTVPtr());
    390453  return row;
    391454}
    392455
    393 MuTyV* BaseDataTable::GetRow(sa_size_t n) const
    394 {
     456/*!
     457  For thread-safe operation, specify a valid \b mtvp  pointer (!= NULL) 
     458*/
     459MuTyV* BaseDataTable::GetRow(sa_size_t n, MuTyV* mtvp) const
     460{
     461  DT_TSOP_SYNC dttss(mThS); dttss.NOp();  // Thread-safe operation
     462
    395463  if ((n < 0) || (n >= NEntry()))
    396464    throw RangeCheckError("BaseDataTable::GetRow() out of range line index n");
    397   if (mVarMTV == NULL) mVarMTV = new MuTyV[NVar()];
    398 
     465  if (mtvp == NULL) {
     466    if (mVarMTV == NULL) mVarMTV = new MuTyV[NVar()];
     467    mtvp = mVarMTV;
     468  }
    399469  sa_size_t bid = n/mSegSz;
    400470  sa_size_t off = n%mSegSz;
    401471  for(sa_size_t k=0; k<mIColsP.size(); k++)
    402     mVarMTV[mIColIdx[k]] = mIColsP[k]->GetCstSegment(bid)[off];
     472    mtvp[mIColIdx[k]] = mIColsP[k]->GetCstSegment(bid)[off];
    403473  for(sa_size_t k=0; k<mLColsP.size(); k++)
    404     mVarMTV[mLColIdx[k]] = mLColsP[k]->GetCstSegment(bid)[off];
     474    mtvp[mLColIdx[k]] = mLColsP[k]->GetCstSegment(bid)[off];
    405475  for(sa_size_t k=0; k<mFColsP.size(); k++)
    406     mVarMTV[mFColIdx[k]] = mFColsP[k]->GetCstSegment(bid)[off];
     476    mtvp[mFColIdx[k]] = mFColsP[k]->GetCstSegment(bid)[off];
    407477  for(sa_size_t k=0; k<mDColsP.size(); k++) {
    408478    if (GetColumType(mDColIdx[k]) == DateTimeField)
    409       mVarMTV[mDColIdx[k]] = TimeStamp(mDColsP[k]->GetCstSegment(bid)[off]);
    410     else mVarMTV[mDColIdx[k]] = mDColsP[k]->GetCstSegment(bid)[off];
     479      mtvp[mDColIdx[k]] = TimeStamp(mDColsP[k]->GetCstSegment(bid)[off]);
     480    else mtvp[mDColIdx[k]] = mDColsP[k]->GetCstSegment(bid)[off];
    411481  }
    412482  for(sa_size_t k=0; k<mYColsP.size(); k++)
    413     mVarMTV[mYColIdx[k]] = mYColsP[k]->GetCstSegment(bid)[off];
     483    mtvp[mYColIdx[k]] = mYColsP[k]->GetCstSegment(bid)[off];
    414484  for(sa_size_t k=0; k<mZColsP.size(); k++)
    415     mVarMTV[mZColIdx[k]] = mZColsP[k]->GetCstSegment(bid)[off];
     485    mtvp[mZColIdx[k]] = mZColsP[k]->GetCstSegment(bid)[off];
    416486  for(sa_size_t k=0; k<mSColsP.size(); k++)
    417     mVarMTV[mSColIdx[k]] = mSColsP[k]->GetCstSegment(bid)[off];
    418 
    419   return mVarMTV;
     487    mtvp[mSColIdx[k]] = mSColsP[k]->GetCstSegment(bid)[off];
     488
     489  return mtvp;
    420490}
    421491
     
    424494TVector<r_8> BaseDataTable::GetColumnD(sa_size_t k) const
    425495{
     496  DT_TSOP_SYNC dttss(mThS); dttss.NOp();  // Thread-safe operation
     497
    426498  if ((k < 0) || (k >= NVar()))
    427499    throw RangeCheckError("BaseDataTable::GetColumnD() out of range column index k");
     
    9681040}
    9691041
     1042} // FIN namespace SOPHYA
     1043
  • trunk/SophyaLib/HiStats/basedtable.h

    r2962 r3392  
    6363  {  row.Print(s);  return(s);  }
    6464
     65//  Forward class declaration for Thread-safe operations
     66class ThSafeOp;
     67
    6568//! Interface definition for classes handling data in a table.
    6669class BaseDataTable : public AnyDataObj , public NTupleInterface {
     
    8184  BaseDataTable(sa_size_t segsz=512);
    8285  virtual           ~BaseDataTable();
     86
     87  // Activate/deactivate thread-safe AddRow()/GetRow() operation
     88  virtual void      SetThreadSafe(bool fg=true);
     89  //! Return true if AddRow()/GetRow()  operations are thread-safe
     90  inline bool       IsThreadSafe() const { return ((mThS)?true:false); }
    8391 
    8492  //! Adds a column holding integer, named \b cnom
     
    193201  virtual DataTableRow&   GetRow(sa_size_t n, DataTableRow& row) const ;
    194202  //! Return the information stored in line (row) \b n of the table
    195   virtual MuTyV *   GetRow(sa_size_t n) const ;
     203  virtual MuTyV *   GetRow(sa_size_t n, MuTyV* mtvp=NULL) const ;
    196204  //! Return the information stored in line \b n of the table. Alias of GetLine
    197205  inline  MuTyV *   GetLine(sa_size_t n) const
     
    316324  std::vector< SegDBInterface<string> * > mSColsP;
    317325  std::vector< sa_size_t > mSColIdx;
     326
     327  ThSafeOp* mThS;       // != NULL -> Thread safe operations
    318328 
    319329};
  • trunk/SophyaLib/HiStats/datatable.cc

    r2849 r3392  
    11#include "datatable.h"
    2 #include "sopnamsp.h"
    32#include "strutil.h"
    43#include "pexceptions.h"
    54#include "fiosegdb.h"
    6 
     5#include "thsafeop.h"
     6
     7namespace SOPHYA {
    78
    89/*!
    9    \class SOPHYA::DataTable
     10   \class DataTable
    1011   \ingroup HiStats
    1112   This class can be used to organize data in table (row-column) form.
     
    6162  The copy constructur shares the data if \b share=true.
    6263  Otherwise, the Clone() method is called to make a complete copy.
     64  This constructor copies also the thread safety state from \b a .
    6365*/
    6466DataTable::DataTable(DataTable const & a, bool share)
     
    7173  if (a.mInfo)  mInfo = new DVList(*(a.mInfo));
    7274}
    73 //! Copy the table structure from \b a and shares the data (columns content)
     75/*!
     76  Copy the table structure from \b a and shares the data (columns content).
     77  The tread-safety state is copied from \b a .
     78*/
    7479void DataTable::Share(DataTable const & a)
    7580{
    7681  // On copie la structure de table
    7782  CopyStructure(a);
     83  if (a.IsThreadSafe())  SetThreadSafe(true);
     84  else SetThreadSafe(false);
    7885  // Et on partage les donnees des colonnes
    7986  for (size_t kk=0; kk<mNames.size(); kk++) {
     
    115122  // On copie la structure de table
    116123  CopyStructure(a);
    117   // Et on partage les donnees des colonnes
     124  if (a.IsThreadSafe())  SetThreadSafe(true);
     125  else SetThreadSafe(false);
     126  // Et on copie les donnees des colonnes
    118127  for (size_t kk=0; kk<mNames.size(); kk++) {
    119128    sa_size_t sk = mNames[kk].ser;
     
    161170  if (mInfo) delete mInfo;
    162171  mInfo = NULL;
     172  if (mThS) delete mThS;
     173  mThS = NULL;
    163174  mMin.clear();
    164175  mMax.clear();
     
    278289}
    279290
     291} // FIN namespace SOPHYA
  • trunk/SophyaLib/HiStats/ntuple.cc

    r3236 r3392  
    55#include "perrors.h"
    66#include "ntuple.h"
     7#include "thsafeop.h"
    78
    89namespace SOPHYA {
     
    1718   Simple NTuple class (a Table or 2-D data set) with double or
    1819   single precision floating point value columns.
     20   \warning
     21   Thread safe fill operation can be activated using the method SetThreadSafe()
     22   Default mode is NON thread-safe fill.
    1923   \sa SOPHYA::ObjFileIO<NTuple>
    2024
     
    6569mFgDouble = true;
    6670mInfo = NULL;
     71mThS = NULL;
    6772}
    6873
     
    8994mVarD = NULL;
    9095mInfo = NULL;
     96mThS = NULL;
    9197if (nvar <= 0)  throw ParmError("NTuple::NTuple(nvar<=0) ");
    9298mNVar = nvar;
     
    126132mVarD = NULL;
    127133mInfo = NULL;
     134mThS = NULL;
    128135int nvar = noms.size();
    129136if (nvar <= 0)  throw ParmError("NTuple::NTuple(nvar<=0) ");
     
    150157}
    151158
    152 //! Copy constructor - Copies the table definition and associated data
     159/*!
     160  Copy constructor - Copies the table definition and associated data,
     161  as well as the tread safety state
     162*/
    153163//                                       cmv 8/10/99
    154164//++
     
    158168//--
    159169: mNVar(0), mNEnt(0), mBlk(0), mNBlk(0)
    160 , mVar(NULL), mVarD(NULL), mInfo(NULL)
     170 , mVar(NULL), mVarD(NULL), mInfo(NULL),mThS(NULL)
    161171{
    162172if(NT.mNVar<=0) return; // cas ou NT est cree par defaut
     
    185195
    186196if(NT.mInfo!=NULL) {mInfo = new DVList; *mInfo = *(NT.mInfo);}
    187 
     197mThS = NULL;
     198if(NT.mThS!=NULL) SetThreadSafe(true);
    188199return;
    189200}
    190201
    191 /* --Methode--
    192 //! Constructor with table initialized from a PPF file
    193 //++
    194 NTuple::NTuple(char *flnm)
    195 //
    196 //      Createur lecture fichier ppersist.
    197 //--
    198 {
    199 mNVar = mNEnt = mBlk = mNBlk = 0;
    200 mVar = NULL;
    201 mVarD = NULL;
    202 mNames = NULL;
    203 mInfo = NULL;
    204 PInPersist s(flnm);
    205 ObjFileIO<NTuple> fiont(this);
    206 fiont.Read(s);
    207 }
     202
     203/* --Methode-- */
     204NTuple::~NTuple()
     205{
     206Clean();
     207}
     208/* --Methode-- */
     209/*!
     210  \brief Activate or deactivate thread-safe \b Fill() operations
     211  If fg==true, create an ThSafeOp object in order to insure atomic Fill()
     212  operations. if fg==false, the ThSafeOp object (mThS) of the target NTuple
     213  is destroyed.
     214  \warning The default Fill() operation mode for NTuples is NOT thread-safe.
     215  Please note also that the thread-safety state is NOt saved to PPF (or FITS) streams.
    208216*/
    209 
    210 /* --Methode-- */
    211 NTuple::~NTuple()
    212 {
    213 Clean();
     217void NTuple::SetThreadSafe(bool fg)
     218{
     219if (fg) {
     220  if (mThS) return;
     221  else mThS = new ThSafeOp();
     222}
     223else {
     224  if (mThS) delete mThS;
     225  mThS = NULL;
     226}
    214227}
    215228
     
    221234if (mVarD) delete[] mVarD;
    222235if (mInfo) delete mInfo;
     236if (mThS) delete mThS;
    223237int i;
    224238if(mNBlk>0) {
     
    232246mVarD = NULL;
    233247mInfo = NULL;
     248mThS = NULL;
    234249return;
    235250}
     
    283298//--
    284299{
     300if (mThS)  mThS->lock();   // Thread-safe operation
    285301int numb = mNEnt/mBlk;
    286302if (numb >= mNBlk) {
     
    302318else memcpy((mPtr[numb]+offb*mNVar), x, mNVar*sizeof(r_4));
    303319mNEnt++;
     320if (mThS)  mThS->unlock();   // Thread-safe operation
    304321return;
    305322}
     
    316333//--
    317334{
     335if (mThS)  mThS->lock();   // Thread-safe operation
    318336int numb = mNEnt/mBlk;
    319337if (numb >= mNBlk) {
     
    337355
    338356mNEnt++;
     357if (mThS)  mThS->unlock();   // Thread-safe operation
    339358return;
    340359}
  • trunk/SophyaLib/HiStats/ntuple.h

    r3205 r3392  
    2121//  Forward class declaration for Fits handler
    2222class FITS_NTuple;
     23//  Forward class declaration for Thread-safe operations
     24class ThSafeOp;
    2325
    2426//! Class for creation and management of double or float data sets in a table
     
    3133  NTuple(const NTuple& NT);
    3234  virtual ~NTuple();
     35
     36  // Activate/deactivate thread-safe Fill operation
     37  void SetThreadSafe(bool fg=true);
     38  //! Return true if Fill  operations are thread-safe
     39  inline bool IsThreadSafe() const { return ((mThS)?true:false); }
    3340
    3441  NTuple& operator = (const NTuple& NT);
     
    102109  DVList* mInfo;        // Infos (variables) attachees au NTuple
    103110 
     111  ThSafeOp* mThS;       // != NULL -> Thread safe operations
    104112};
    105113
  • trunk/SophyaLib/HiStats/swppfdtable.cc

    r3031 r3392  
    11#include "swppfdtable.h"
    2 #include "sopnamsp.h"
    32#include "pexceptions.h"
    4 
     3#include "thsafeop.h"
     4
     5namespace SOPHYA {
    56
    67/*!
    7    \class SOPHYA::SwPPFDataTable
     8   \class SwPPFDataTable
    89   \ingroup HiStats
    910   This class can be used to organize data in table (row-column) form.
     
    9697}
    9798
    98 //! copy constructor - shares the data
     99//! copy constructor - shares the data (and copies the thread safety state)
     100
    99101SwPPFDataTable::SwPPFDataTable(SwPPFDataTable const & a)
    100102  : BaseDataTable(a.SegmentSize()),
     
    137139  // On copie la structure de table
    138140  CopyStructure(a);
     141  if (a.IsThreadSafe())  SetThreadSafe(true);
     142  else SetThreadSafe(false);
    139143
    140144  //
     
    229233  if (mInfo) delete mInfo;
    230234  mInfo = NULL;
     235  if (mThS) delete mThS;
     236  mThS = NULL;
    231237  mMin.clear();
    232238  mMax.clear();
     
    355361  // On est oblige de calculer les min-max lors du remplissage
    356362  // On ne peut pas en effet 'relire' le swap pendant l'ecriture
     363  if (mThS) mThS->lock();   // tread-safety
    357364  for(sa_size_t k=0; k<NVar(); k++) {
    358365    double x = data[k];
     
    361368    mMinMaxNEnt[k]++;
    362369  }
     370  if (mThS) mThS->unlock(); // tread-safety
    363371  return BaseDataTable::AddRow(data);
    364372}
     
    373381  // On est oblige de calculer les min-max lors du remplissage
    374382  // On ne peut pas en effet 'relire' le swap pendant l'ecriture
     383  if (mThS) mThS->lock();   // tread-safety
    375384  for(sa_size_t k=0; k<NVar(); k++) {
    376385    double x = (double)data[k];
     
    379388    mMinMaxNEnt[k]++;
    380389  }
     390  if (mThS) mThS->unlock(); // tread-safety
    381391  return BaseDataTable::AddRow(data);
    382392}
     
    394404  return AddRow(data.MTVPtr());
    395405}
     406
     407} // FIN namespace SOPHYA
Note: See TracChangeset for help on using the changeset viewer.