source: Sophya/trunk/SophyaLib/HiStats/swppfdtable.cc@ 2808

Last change on this file since 2808 was 2808, checked in by ansari, 20 years ago

MAJ documentation - Reza 14/6/2005

File size: 9.1 KB
Line 
1#include "swppfdtable.h"
2#include "sopnamsp.h"
3#include "pexceptions.h"
4
5
6/*!
7 \class SOPHYA::SwPPFDataTable
8 \ingroup HiStats
9 This class can be used to organize data in table (row-column) form.
10 Each column holds homogeneous data (same data type), while different
11 columns can be used for different data types
12 (integer, float, string ...).
13 A PPF stream is used as swap space. Due to limitations in the current
14 implementation of PPF streams, read operations (acces to table data) cannot
15 be performed when a table is being filled.
16
17 \warning
18 - When creating a table, the output PPF stream (POutPersist) must not be closed
19 (destroyed) before the call to the SwPPFDataTable object.
20 - It is not possible to make a complete (deep) copy of a table SwPPFDataTable
21 Copy constructor and equal operator shares the data.
22 - Although the destructor DOES NOT save the
23 table object itself to the memory. You have to use the << operator on the
24 output PPF stream being used as swap
25
26 \sa SOPHYA::MuTyV
27 \sa SOPHYA::DataTable
28 \sa SOPHYA::SwSegDataBlock SOPHYA::PPFDataSwapper
29
30 \code
31 #include "swppfdtable.h"
32 // ...
33 {
34 // ---- Creation of the table
35 // Create the swap stream
36 POutPersist so("myswtable.ppf");
37 SwPPFDataTable dt(so, 64);
38 // define table columns
39 dt.AddFloatColumn("X0_f");
40 dt.AddFloatColumn("X1_f");
41 dt.AddDoubleColumn("X0X0pX1X1_d");
42 // Fill the table
43 MuTyV x[5];
44 for(int i=0; i<63; i++) {
45 x[0] = (i%9)-4.; x[1] = (i/9)-3.; x[2] = x[0]*x[0]+x[1]*x[1];
46 dt.AddLine(x);
47 }
48 // Printing table info
49 cout << dt ;
50 // Swap out all data and write the table structure to the PPF stream
51 so << dt ;
52 // ....
53 }
54 {
55 // ---- Accessing information from a previously created table
56 SwPPFDataTable dt;
57 PInPersist si("myswtable.ppf");
58 si >> dt;
59 // Printing table info
60 cout << dt ;
61 }
62 \endcode
63*/
64//! Default constructor with optional specification of block (or segment) size
65SwPPFDataTable::SwPPFDataTable(sa_size_t segsz)
66 : BaseDataTable(segsz),
67 mSwOut(NULL), mSwIn(NULL)
68{
69}
70/*! Constructor with the specification of the output swap stream -
71 and optional specification of block (or segment) size
72*/
73SwPPFDataTable::SwPPFDataTable(POutPersist & os, sa_size_t segsz)
74 : BaseDataTable(segsz) ,
75 mSwOut(&os), mSwIn(NULL),
76 mISwapper(os), mLSwapper(os), mFSwapper(os), mDSwapper(os), mSSwapper(os)
77{
78}
79//! Protected constructor for creation from a swap stream
80SwPPFDataTable::SwPPFDataTable(PInPersist & is, sa_size_t segsz)
81 : BaseDataTable(segsz) ,
82 mSwOut(NULL), mSwIn(NULL)
83{
84 PInPersist* pis = new PInPersist(is.FileName(), false);
85 mSwIn = new St_InSwap;
86 mSwIn->pis = pis; mSwIn->refcnt = 1;
87 mISwapper.SetInStream(*pis);
88 mLSwapper.SetInStream(*pis);
89 mFSwapper.SetInStream(*pis);
90 mDSwapper.SetInStream(*pis);
91 mDSwapper.SetInStream(*pis);
92}
93
94//! copy constructor - shares the data
95SwPPFDataTable::SwPPFDataTable(SwPPFDataTable const & a)
96 : BaseDataTable(a.SegmentSize()),
97 mSwOut(NULL), mSwIn(NULL)
98{
99 Share(a);
100}
101//! Destructor - Deletes / closes the input PPF swap stream
102SwPPFDataTable::~SwPPFDataTable()
103{
104 if (mSwIn) {
105 mSwIn->refcnt--;
106 if (mSwIn->refcnt == 0) {
107 delete mSwIn->pis;
108 delete mSwIn;
109 mSwIn = NULL;
110 }
111 }
112}
113
114void SwPPFDataTable::Share(SwPPFDataTable const & a)
115{
116 // Recopie (attention !) brutale des swappers et les streams associes
117 mISwapper = a.mISwapper;
118 mLSwapper = a.mLSwapper;
119 mFSwapper = a.mFSwapper;
120 mDSwapper = a.mDSwapper;
121 mSSwapper = a.mSSwapper;
122
123 mSwOut = a.mSwOut;
124 mSwIn = a.mSwIn;
125 if (mSwIn) mSwIn->refcnt++; // comptage de reference pour le stream input
126
127 // On recopie la taille de segment
128 mSegSz = a.SegmentSize();
129 if (a.NVar() == 0) return; // Table sans colonne
130
131 // On copie la structure de table
132 CopyStructure(a);
133
134 //
135 // Update nombre d'entree, ...
136 mNEnt = a.mNEnt;
137 mNSeg = a.mNSeg;
138 if (a.mInfo) mInfo = new DVList(*(a.mInfo));
139
140 // mis a jour des tableax min-max
141 mMin = a.mMin;
142 mMax = a.mMax;
143 mMinMaxNEnt = a.mMinMaxNEnt;
144
145 // Et on partage les donnees des colonnes
146 for (size_t kk=0; kk<mNames.size(); kk++) {
147 sa_size_t sk = mNames[kk].ser;
148 sa_size_t ska = a.mNames[kk].ser;
149 switch (mNames[kk].type) {
150 case IntegerField :
151 mICols[sk] = a.mICols[ska];
152 break;
153 case LongField :
154 mLCols[sk] = a.mLCols[ska];
155 break;
156 case FloatField :
157 mFCols[sk] = a.mFCols[ska];
158 break;
159 case DoubleField :
160 mDCols[sk] = a.mDCols[ska];
161 break;
162 case StringField :
163 mSCols[sk] = a.mSCols[ska];
164 break;
165 default:
166 throw ForbiddenError("SwPPFDataTable::Share() : unknown column type ");
167 break;
168 }
169 }
170}
171void SwPPFDataTable::SwapOutAll() const
172{
173 // Et on vide les buffers de swap
174 for (size_t kk=0; kk<mNames.size(); kk++) {
175 sa_size_t sk = mNames[kk].ser;
176 switch (mNames[kk].type) {
177 case IntegerField :
178 mICols[sk].SwapOutBuffer();
179 break;
180 case LongField :
181 mLCols[sk].SwapOutBuffer();
182 break;
183 case FloatField :
184 mFCols[sk].SwapOutBuffer();
185 break;
186 case DoubleField :
187 mDCols[sk].SwapOutBuffer();
188 break;
189 case StringField :
190 mSCols[sk].SwapOutBuffer();
191 break;
192 default:
193 throw ForbiddenError("SwPPFDataTable::Share() : unknown column type ");
194 break;
195 }
196 }
197}
198
199void SwPPFDataTable::Clear()
200{
201 if ( (NVar() == 0) && (NEntry() == 0)) return;
202 mNEnt = 0;
203 mNSeg = 0;
204 if (mVarD) delete[] mVarD;
205 mVarD = NULL;
206 if (mVarMTV) delete[] mVarMTV;
207 mVarMTV = NULL;
208 mNames.clear();
209 if (mInfo) delete mInfo;
210 mInfo = NULL;
211 mMin.clear();
212 mMax.clear();
213 mMinMaxNEnt.clear();
214 mIColsP.clear();
215 mLColsP.clear();
216 mFColsP.clear();
217 mDColsP.clear();
218 mSColsP.clear();
219
220 mIColIdx.clear();
221 mLColIdx.clear();
222 mFColIdx.clear();
223 mDColIdx.clear();
224 mSColIdx.clear();
225
226 mICols.clear();
227 mLCols.clear();
228 mFCols.clear();
229 mDCols.clear();
230 mSCols.clear();
231}
232
233
234/*!
235 Implements the action defined in the BaseDataTable interface.
236 In the current implementation, throws an exception (ParmError)
237 if the table contains some data already.
238*/
239sa_size_t SwPPFDataTable::AddColumn(FieldType ft, string const & cnom)
240{
241 if (NEntry() > 0)
242 throw ParmError("SwPPFDataTable::AddColumn() Table contains already data ");
243 CheckColName(cnom);
244 sa_size_t ser;
245 sa_size_t idx = NVar();
246 switch (ft) {
247 case IntegerField :
248 ser = mICols.size();
249 mICols.push_back(SwSegDataBlock<int_4>(mISwapper, mSegSz));
250 mIColIdx.push_back(idx);
251 mIColsP.push_back(NULL);
252 for(sa_size_t kk=0; kk<mICols.size(); kk++)
253 mIColsP[kk] = &(mICols[kk]);
254 break;
255 case LongField :
256 ser = mLCols.size();
257 mLCols.push_back(SwSegDataBlock<int_8>(mLSwapper, mSegSz));
258 mLColIdx.push_back(idx);
259 mLColsP.push_back(NULL);
260 for(sa_size_t kk=0; kk<mLCols.size(); kk++)
261 mLColsP[kk] = &(mLCols[kk]);
262 break;
263 case FloatField :
264 ser = mFCols.size();
265 mFCols.push_back(SwSegDataBlock<r_4>(mFSwapper, mSegSz));
266 mFColIdx.push_back(idx);
267 mFColsP.push_back(NULL);
268 for(sa_size_t kk=0; kk<mFCols.size(); kk++)
269 mFColsP[kk] = &(mFCols[kk]);
270 break;
271 case DoubleField :
272 ser = mDCols.size();
273 mDCols.push_back(SwSegDataBlock<r_8>( mDSwapper,mSegSz));
274 mDColIdx.push_back(idx);
275 mDColsP.push_back(NULL);
276 for(sa_size_t kk=0; kk<mDCols.size(); kk++)
277 mDColsP[kk] = &(mDCols[kk]);
278 break;
279 case StringField :
280 ser = mDCols.size();
281 mSCols.push_back(SwSegDataBlock<string>(mSSwapper, mSegSz));
282 mSColIdx.push_back(idx);
283 mSColsP.push_back(NULL);
284 for(sa_size_t kk=0; kk<mSCols.size(); kk++)
285 mSColsP[kk] = &(mSCols[kk]);
286 break;
287 default:
288 throw ParmError("SwPPFDataTable::AddColumn() unknown field type ");
289 break;
290 }
291 colst col;
292 col.nom = cnom;
293 col.type = ft;
294 col.ser = ser;
295 mNames.push_back(col);
296 // On est oblige de calculer les min-max lors du remplissage
297 // On ne peut pas en effet 'relire' le swap pendant l'ecriture
298 mMin.push_back(0.);
299 mMax.push_back(0.);
300 mMinMaxNEnt.push_back(0);
301
302 return NVar();
303}
304
305//! Adds a line (or row to the table) with r_8* input data.
306/*!
307 The min/max values for each column is updated, in addition
308 to the actions performed by the base class AddLine()
309*/
310sa_size_t SwPPFDataTable::AddLine(const r_8* data)
311{
312 // On est oblige de calculer les min-max lors du remplissage
313 // On ne peut pas en effet 'relire' le swap pendant l'ecriture
314 for(sa_size_t k=0; k<NVar(); k++) {
315 double x = data[k];
316 if (x < mMin[k]) mMin[k] = x;
317 if (x > mMax[k]) mMax[k] = x;
318 mMinMaxNEnt[k]++;
319 }
320 return BaseDataTable::AddLine(data);
321}
322
323//! Adds a line (or row to the table) with input data as an array of MuTyV
324/*!
325 The min/max values for each column is updated, in addition
326 to the actions performed by the base class AddLine()
327*/
328sa_size_t SwPPFDataTable::AddLine(const MuTyV * data)
329{
330 // On est oblige de calculer les min-max lors du remplissage
331 // On ne peut pas en effet 'relire' le swap pendant l'ecriture
332 for(sa_size_t k=0; k<NVar(); k++) {
333 double x = (double)data[k];
334 if (x < mMin[k]) mMin[k] = x;
335 if (x > mMax[k]) mMax[k] = x;
336 mMinMaxNEnt[k]++;
337 }
338 return BaseDataTable::AddLine(data);
339}
340
Note: See TracBrowser for help on using the repository browser.