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

File:
1 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
Note: See TracChangeset for help on using the changeset viewer.