source: Sophya/trunk/SophyaLib/HiStats/datatable.cc@ 3922

Last change on this file since 3922 was 3392, checked in by ansari, 18 years ago

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

File size: 7.5 KB
Line 
1#include "datatable.h"
2#include "strutil.h"
3#include "pexceptions.h"
4#include "fiosegdb.h"
5#include "thsafeop.h"
6
7namespace SOPHYA {
8
9/*!
10 \class DataTable
11 \ingroup HiStats
12 This class can be used to organize data in table (row-column) form.
13 Each column holds homogeneous data (same data type), while different
14 columns can be used for different data types
15 (integer, float, string ...).
16 The whole data set is kept in memory.
17 \sa SOPHYA::MuTyV
18 \sa SOPHYA::DataTableRow
19 \sa SOPHYA::BaseDataTable
20 \sa SOPHYA::SegDataBlock
21
22 \code
23 #include "datatable.h"
24 // ...
25 DataTable dt(64);
26 dt.AddFloatColumn("X0_f");
27 dt.AddFloatColumn("X1_f");
28 dt.AddDoubleColumn("X0X0pX1X1_d");
29 double x[5];
30 for(int i=0; i<63; i++) {
31 x[0] = (i%9)-4.; x[1] = (i/9)-3.; x[2] = x[0]*x[0]+x[1]*x[1];
32 dt.AddRow(x);
33 }
34 // Printing table info
35 cout << dt ;
36 // Saving object into a PPF file
37 POutPersist po("dtable.ppf");
38 po << dt ;
39 \endcode
40
41 DataTableRow objects can also be used to fill the table, or access the data, as
42 shown in the example below:
43 \code
44 // We use the same table as in the example above:
45 DataTableRow row = dt.EmptyRow();
46 row[0] = 83.3; row[1] = 20.; row[2] = 83.3*83.3+20.*20.;
47 dt.AddRow(row);
48 row["X0_f"] = 7.5; row["X1_f"] = 6.; row["X0X0pX1X1_d"] = 7.5*7.5+6.*6.;
49 dt.AddRow(row);
50 \endcode
51*/
52
53
54//! Default constructor - optional specification of block (or segment) size
55DataTable::DataTable(sa_size_t segsz)
56 : BaseDataTable(segsz)
57{
58}
59
60//! copy constructor
61/*!
62 The copy constructur shares the data if \b share=true.
63 Otherwise, the Clone() method is called to make a complete copy.
64 This constructor copies also the thread safety state from \b a .
65*/
66DataTable::DataTable(DataTable const & a, bool share)
67 : BaseDataTable(a.SegmentSize())
68{
69 if (share) Share(a);
70 else Clone(a);
71 mNEnt = a.mNEnt;
72 mNSeg = a.mNSeg;
73 if (a.mInfo) mInfo = new DVList(*(a.mInfo));
74}
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*/
79void DataTable::Share(DataTable const & a)
80{
81 // On copie la structure de table
82 CopyStructure(a);
83 if (a.IsThreadSafe()) SetThreadSafe(true);
84 else SetThreadSafe(false);
85 // Et on partage les donnees des colonnes
86 for (size_t kk=0; kk<mNames.size(); kk++) {
87 sa_size_t sk = mNames[kk].ser;
88 sa_size_t ska = a.mNames[kk].ser;
89 switch (mNames[kk].type) {
90 case IntegerField :
91 mICols[sk].Share(a.mICols[ska]);
92 break;
93 case LongField :
94 mLCols[sk].Share(a.mLCols[ska]);
95 break;
96 case FloatField :
97 mFCols[sk].Share(a.mFCols[ska]);
98 break;
99 case DoubleField :
100 case DateTimeField :
101 mDCols[sk].Share(a.mDCols[ska]);
102 break;
103 case ComplexField :
104 mYCols[sk].Share(a.mYCols[ska]);
105 break;
106 case DoubleComplexField :
107 mZCols[sk].Share(a.mZCols[ska]);
108 break;
109 case StringField :
110 mSCols[sk].Share(a.mSCols[ska]);
111 break;
112 default:
113 throw ForbiddenError("DataTable::Share() : unknown column type ");
114 break;
115 }
116 }
117}
118
119//! Copy the table structure from \b a and duplicate (copy) the data (columns content)
120void DataTable::Clone(DataTable const & a)
121{
122 // On copie la structure de table
123 CopyStructure(a);
124 if (a.IsThreadSafe()) SetThreadSafe(true);
125 else SetThreadSafe(false);
126 // Et on copie les donnees des colonnes
127 for (size_t kk=0; kk<mNames.size(); kk++) {
128 sa_size_t sk = mNames[kk].ser;
129 sa_size_t ska = a.mNames[kk].ser;
130 switch (mNames[kk].type) {
131 case IntegerField :
132 mICols[sk].Clone(a.mICols[ska], true);
133 break;
134 case LongField :
135 mLCols[sk].Clone(a.mLCols[ska], true);
136 break;
137 case FloatField :
138 mFCols[sk].Clone(a.mFCols[ska], true);
139 break;
140 case DoubleField :
141 case DateTimeField :
142 mDCols[sk].Clone(a.mDCols[ska], true);
143 break;
144 case ComplexField :
145 mYCols[sk].Clone(a.mYCols[ska], true);
146 break;
147 case DoubleComplexField :
148 mZCols[sk].Clone(a.mZCols[ska], true);
149 break;
150 case StringField :
151 mSCols[sk].Clone(a.mSCols[ska], true);
152 break;
153 default:
154 throw ForbiddenError("DataTable::Clone() : unknown column type ");
155 break;
156 }
157 }
158}
159//! Reset (/clear) the table content and structure
160void DataTable::Clear()
161{
162 if ( (NVar() == 0) && (NEntry() == 0)) return;
163 mNEnt = 0;
164 mNSeg = 0;
165 if (mVarD) delete[] mVarD;
166 mVarD = NULL;
167 if (mVarMTV) delete[] mVarMTV;
168 mVarMTV = NULL;
169 mNames.clear();
170 if (mInfo) delete mInfo;
171 mInfo = NULL;
172 if (mThS) delete mThS;
173 mThS = NULL;
174 mMin.clear();
175 mMax.clear();
176 mMinMaxNEnt.clear();
177 mIColsP.clear();
178 mLColsP.clear();
179 mFColsP.clear();
180 mDColsP.clear();
181 mYColsP.clear();
182 mZColsP.clear();
183 mSColsP.clear();
184
185 mIColIdx.clear();
186 mLColIdx.clear();
187 mFColIdx.clear();
188 mDColIdx.clear();
189 mYColIdx.clear();
190 mZColIdx.clear();
191 mSColIdx.clear();
192
193 mICols.clear();
194 mLCols.clear();
195 mFCols.clear();
196 mDCols.clear();
197 mYCols.clear();
198 mZCols.clear();
199 mSCols.clear();
200}
201
202
203/*!
204 Implements the action defined in the BaseDataTable interface.
205 In the current implementation, throws an exception (ParmError)
206 if the table contains some data already.
207*/
208sa_size_t DataTable::AddColumn(FieldType ft, string const & cnom)
209{
210 if (NEntry() > 0)
211 throw ParmError("DataTable::AddColumn() Table contains already data ");
212 CheckColName(cnom);
213 sa_size_t ser;
214 sa_size_t idx = NVar();
215 switch (ft) {
216 case IntegerField :
217 ser = mICols.size();
218 mICols.push_back(SegDataBlock<int_4>(mSegSz));
219 mIColIdx.push_back(idx);
220 mIColsP.push_back(NULL);
221 for(sa_size_t kk=0; kk<mICols.size(); kk++)
222 mIColsP[kk] = &(mICols[kk]);
223 break;
224 case LongField :
225 ser = mLCols.size();
226 mLCols.push_back(SegDataBlock<int_8>(mSegSz));
227 mLColIdx.push_back(idx);
228 mLColsP.push_back(NULL);
229 for(sa_size_t kk=0; kk<mLCols.size(); kk++)
230 mLColsP[kk] = &(mLCols[kk]);
231 break;
232 case FloatField :
233 ser = mFCols.size();
234 mFCols.push_back(SegDataBlock<r_4>(mSegSz));
235 mFColIdx.push_back(idx);
236 mFColsP.push_back(NULL);
237 for(sa_size_t kk=0; kk<mFCols.size(); kk++)
238 mFColsP[kk] = &(mFCols[kk]);
239 break;
240 case DoubleField :
241 case DateTimeField :
242 ser = mDCols.size();
243 mDCols.push_back(SegDataBlock<r_8>(mSegSz));
244 mDColIdx.push_back(idx);
245 mDColsP.push_back(NULL);
246 for(sa_size_t kk=0; kk<mDCols.size(); kk++)
247 mDColsP[kk] = &(mDCols[kk]);
248 break;
249 case ComplexField :
250 ser = mYCols.size();
251 mYCols.push_back(SegDataBlock< complex<r_4> >(mSegSz));
252 mYColIdx.push_back(idx);
253 mYColsP.push_back(NULL);
254 for(sa_size_t kk=0; kk<mYCols.size(); kk++)
255 mYColsP[kk] = &(mYCols[kk]);
256 break;
257 case DoubleComplexField :
258 ser = mZCols.size();
259 mZCols.push_back(SegDataBlock< complex<r_8> >(mSegSz));
260 mZColIdx.push_back(idx);
261 mZColsP.push_back(NULL);
262 for(sa_size_t kk=0; kk<mZCols.size(); kk++)
263 mZColsP[kk] = &(mZCols[kk]);
264 break;
265 case StringField :
266 ser = mSCols.size();
267 mSCols.push_back(SegDataBlock<string>(mSegSz));
268 mSColIdx.push_back(idx);
269 mSColsP.push_back(NULL);
270 for(sa_size_t kk=0; kk<mSCols.size(); kk++)
271 mSColsP[kk] = &(mSCols[kk]);
272 break;
273 default:
274 throw ParmError("DataTable::AddColumn() unknown field type ");
275 break;
276 }
277 colst col;
278 col.nom = cnom;
279 col.type = ft;
280 col.ser = ser;
281 mNames.push_back(col);
282
283 // Tableaux de calcul min-max
284 mMin.push_back(0.);
285 mMax.push_back(0.);
286 mMinMaxNEnt.push_back(0);
287
288 return NVar();
289}
290
291} // FIN namespace SOPHYA
Note: See TracBrowser for help on using the repository browser.