source: Sophya/trunk/SophyaLib/BaseTools/swsegdb.h@ 2805

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

MAJ commentaires pour documentation doxygen - Reza 9 Juin 2005

File size: 6.8 KB
RevLine 
[2660]1// This may look like C code, but it is really -*- C++ -*-
2// Gestion de block de donnees swapable
3// R. Ansari Mars 2005
4// LAL (Orsay) / IN2P3-CNRS DAPNIA/SPP (Saclay) / CEA
5#ifndef SWSEGDATABLOCK_H
6#define SWSEGDATABLOCK_H
7
8#include "machdefs.h"
9#include "segdatablock.h"
10#include "pexceptions.h"
11#include <vector>
12#include <typeinfo>
13
[2805]14/*!
15 \class SOPHYA::DataSwapperInterface
16 \ingroup BaseTools
17 Interface definition for data swapper (pure virtual) classes to be used
18 with SOPHYA::SwSegDataBlock classes.
19*/
20/*!
21 \class SOPHYA::SwSegDataBlock
22 \ingroup BaseTools
23 Segmented data structure with swap space management.
24*/
25
[2660]26namespace SOPHYA {
27
28////////////////////////////////////////////////////////////////
29//// ------------- Class DataSwapperInterface --------------- //
30//// ---------------- Class SwSegDataBlock ------------------ //
31////////////////////////////////////////////////////////////////
32
33template <class T>
34class DataSwapperInterface {
35public:
36 virtual ~DataSwapperInterface() { }
[2805]37 /*! Swap out the data array pointed by \b d with size \b sz
38 Return the swap position which might be used later to retrieve the data from swap
39 \param d : Pointer to the memory segment
40 \param sz : Number of elements (type T)
41 \param idx : An integer which might be used to identify the data (optional)
42 \param oswp : Old swap position, if the data has already been swapped
43 \param osw : true -> data has already been swapped
44 */
[2660]45 virtual int_8 WriteToSwap(const T * d, size_t sz, int_8 idx, int_8 oswp=0, bool osw=false) = 0;
[2805]46 /*! Swap in the data array pointed by \b d with size \b sz
47 Retrieves the data from swap space and copies it to \b d
48 \param idx : optional data identifier
49 \param swp : swap position (obtained from a previous call to WriteToSwap()
50 \param d : pointer to T , where the data will be copied from swap space
51 \param sz : Number of data elements (type T)
52 */
[2660]53 virtual void ReadFromSwap(int_8 idx, int_8 swp, T* d, size_t sz) = 0;
54};
55
56template <class T>
57class SwSegDataBlock : public SegDBInterface<T> {
58public:
59 //! Constructor - creation from swap position tags (values)
60 SwSegDataBlock(DataSwapperInterface<T> & dsw, vector<int_8> const & swpos, size_t segsz)
61 {
62 mSRef = NULL;
63 SetSize(segsz, swpos.size());
64 mSRef->swapper = &dsw;
65 mSRef->swp = swpos;
66 for(size_t k=0; k<mSRef->fgwp.size(); k++) mSRef->fgwp[k] = true;
67 }
68 //! Constructor - optional specification of segment size and number of segments
69 SwSegDataBlock(DataSwapperInterface<T> & dsw, size_t segsz=32, size_t nbseg=0)
70 {
71 mSRef = NULL;
72 SetSize(segsz, nbseg);
73 mSRef->swapper = &dsw;
74 }
75 //! copy constructor - shares the data
76 SwSegDataBlock(const SwSegDataBlock<T>& a)
77 {
78 mSRef = a.mSRef;
79 mSRef->nref++;
80 }
81
82 //! Destructor. The memory is freed when the last object referencing the data segment is destroyed
83 virtual ~SwSegDataBlock() { Delete(); }
84 //! Adds one segment to the data structure - returns the pointer to the allocated segment.
85 virtual size_t Extend()
86 {
87 mSRef->swp.push_back(0);
88 mSRef->fgwp.push_back(false);
89 return mSRef->swp.size();
90 }
91 //! Changes the data segment size and reallocates the memory segments
92 // segsz : Segment size ; nbseg : Number of data segments
93 virtual void SetSize(size_t segsz, size_t nbseg=0)
94 {
95 Delete();
96 mSRef = new SWSDREF;
97 mSRef->nref = 1;
98 mSRef->segsize = segsz;
99 mSRef->dsid = AnyDataObj::getUniqueId();
100 mSRef->buff = new T[segsz];
101 mSRef->bidx = -1;
102 mSRef->fgcstbuff = true;
103 for(size_t k=0; k<nbseg; k++) {
104 mSRef->swp.push_back(0);
105 mSRef->fgwp.push_back(false);
106 }
107 }
108 //! Return the segment size data structure
109 virtual size_t SegmentSize() const { return mSRef->segsize; }
110 //! Return the number of data segments
111 virtual size_t NbSegments() const { return mSRef->swp.size(); } ;
112 //! Return the current size of the segmented data structure
113 inline size_t Size() const { return mSRef->swp.size()*mSRef->segsize; }
[2698]114 //! Return the pointer to data segment \b k
[2660]115 virtual T* GetSegment(size_t k)
116 {
117 getSeg(k);
118 mSRef->fgcstbuff = false;
119 return mSRef->buff;
120 }
[2698]121 //! Return the const (read-only) pointer to data segment \b k
122 virtual T const * GetCstSegment(size_t k) const
[2660]123 {
124 getSeg(k);
125 mSRef->fgcstbuff = true;
126 return mSRef->buff;
127 }
[2692]128
129 //! Equal operator. Shares the data with \b a
130 inline SwSegDataBlock<T>& operator = (const SwSegDataBlock<T>& a)
131 {
132 Delete();
133 mSRef = a.mSRef;
134 mSRef->nref++;
[2695]135 return *this;
[2692]136 }
137
[2695]138 //! Empties all memory buffers to swap stream
139 void SwapOutBuffer() const
140 {
[2660]141 if ((mSRef->bidx >= 0) && !mSRef->fgcstbuff) {
142 int_8 nswp = mSRef->swapper->WriteToSwap(mSRef->buff, mSRef->segsize, mSRef->bidx,
143 mSRef->swp[mSRef->bidx], mSRef->fgwp[mSRef->bidx]);
144 mSRef->swp[mSRef->bidx] = nswp;
145 mSRef->fgwp[mSRef->bidx] = true;
[2695]146 mSRef->bidx = -1;
147 mSRef->fgcstbuff = true;
148 }
149 }
150 //! Return the position tag (swap position) table, after call to SwapOutBuffer()
151 std::vector< int_8 > & GetSwapPosTagTable() const
152 {
153 SwapOutBuffer();
[2660]154 return mSRef->swp;
155 }
156
157protected:
158 SwSegDataBlock()
159 {
160 throw ForbiddenError("SwSegDataBlock() default constructor not allowed (swsegdb.h)");
161 }
162 void Delete()
163 {
164 if (mSRef == NULL) return;
165 mSRef->nref--;
166 if (mSRef->nref > 0) { mSRef = NULL; return; }
167 delete[] mSRef->buff;
168 delete mSRef;
169 mSRef = NULL;
170 }
171 void getSeg(size_t k) const
172 {
173 if (k == mSRef->bidx) return ;
174 if ((mSRef->bidx >= 0) && !mSRef->fgcstbuff) {
175 int_8 nswp = mSRef->swapper->WriteToSwap(mSRef->buff, mSRef->segsize, mSRef->bidx,
176 mSRef->swp[mSRef->bidx], mSRef->fgwp[mSRef->bidx]);
177 mSRef->swp[mSRef->bidx] = nswp;
178 mSRef->fgwp[mSRef->bidx] = true;
179 }
180 if (mSRef->fgwp[k])
181 mSRef->swapper->ReadFromSwap(k, mSRef->swp[k], mSRef->buff, mSRef->segsize);
182 else { delete[] mSRef->buff; mSRef->buff = new T[mSRef->segsize]; }
183 mSRef->bidx = k;
184 return;
185 }
186
[2805]187 //! \cond
[2660]188 typedef struct {
189 size_t nref; // Number of references to the data structure
190 uint_8 dsid; // Data structure id
191 size_t segsize; // data segment size
192 mutable std::vector< int_8 > swp; // swap position tag for each segment
193 mutable std::vector< bool > fgwp; // swap flag (true = already swapped) for each segment
194 mutable T * buff; // Data buffer
195 mutable int_8 bidx; // segment index (number) corresponding to buffer
196 mutable bool fgcstbuff; // true : this is a constant T * buff<
197 DataSwapperInterface<T> * swapper; // Data swapper
198 } SWSDREF;
[2805]199 //! \endcond
[2660]200 SWSDREF * mSRef; // SWSDREF structure for reference sharing
201};
202
203
204} // Fin du namespace
205
206#endif
Note: See TracBrowser for help on using the repository browser.