source: Sophya/trunk/SophyaLib/BaseTools/segdatablock.h@ 2692

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

Ajout operateur = pour SegDataBlock<T> SwSegDataBlock<T> pour eviter l utilisation d'un operateur = genere par le compilo - Reza 26/4/2005

File size: 8.3 KB
Line 
1// This may look like C code, but it is really -*- C++ -*-
2// Gestion de block de donnees avec partage de references
3// R. Ansari Mars 2005
4// LAL (Orsay) / IN2P3-CNRS DAPNIA/SPP (Saclay) / CEA
5#ifndef SEGDATABLOCK_H
6#define SEGDATABLOCK_H
7
8#include "machdefs.h"
9#include "anydataobj.h"
10#include <string.h>
11#include <vector>
12#include <iostream>
13#include <iomanip>
14#include <typeinfo>
15
16namespace SOPHYA {
17
18////////////////////////////////////////////////////////////////
19//// ---------------- Class SegDBInterface ------------------ //
20//// ----------------- Class SegDataBlock ------------------- //
21////////////////////////////////////////////////////////////////
22
23/*!
24 \class SOPHYA::SegDBInterface
25 \ingroup BaseTools
26 Interface definition for segmented data container (template class).
27*/
28template <class T>
29class SegDBInterface : public AnyDataObj {
30public:
31 virtual ~SegDBInterface() {}
32 //! Changes the data segment size and reallocates the memory segments
33 // segsz : Segment size ; nbseg : Number of data segments
34 virtual void SetSize(size_t segsz, size_t nbseg=0) = 0;
35 //! Alias for SetSize()
36 inline void ReSize(size_t segsz, size_t nbseg=0) { SetSize(segsz, nbseg); }
37 //! Adds one segment to the data structure - returns the new number of segments.
38 virtual size_t Extend() = 0;
39 //! Return the segment size data structure
40 virtual size_t SegmentSize() const = 0;
41 //! Return the number of data segments
42 virtual size_t NbSegments() const = 0;
43 //! Return the current size of the segmented data structure
44 inline size_t Size() const { return SegmentSize()*NbSegments(); }
45 //! Return pointer to data segment \b k
46 virtual T* GetSegment(size_t k) = 0;
47 virtual T const * GetSegment(size_t k) const = 0;
48};
49
50// classe de container avec partage de reference
51//! Segmented data container with reference sharing
52/*!
53 \class SOPHYA::SegDataBlock
54 \ingroup BaseTools
55 Template class impementing segmented data container in memory with
56 management of reference sharing.
57*/
58template <class T>
59class SegDataBlock : public SegDBInterface<T> {
60
61public:
62
63 //! Default constructor - optional specification of segment size and number of segments
64 explicit SegDataBlock(size_t segsz=32, size_t nbseg=0)
65 {
66 mSRef = NULL;
67 SetSize(segsz, nbseg);
68 }
69 //! copy constructor - shares the data
70 SegDataBlock(const SegDataBlock<T>& a)
71 {
72 mSRef = a.mSRef;
73 mSRef->nref++;
74 }
75 //! copy constructor with specification of flags for data sharing and element value copy
76 SegDataBlock(const SegDataBlock<T>& a, bool share, bool cpval=true)
77 {
78 if (share) {
79 mSRef = a.mSRef;
80 mSRef->nref++;
81 }
82 else {
83 mSRef = NULL;
84 Clone(a, cpval);
85 }
86 }
87 //! copy constructor - shares the data if \b is a SegDataBlock, clones otherwise
88 SegDataBlock(const SegDBInterface<T>& a)
89 {
90 SegDataBlock<T> * sdb = dynamic_cast< SegDataBlock<T> *>(&a);
91 if (p != NULL) {
92 mSRef = p->mSRef;
93 mSRef->nref++;
94 }
95 else Clone(a, true);
96 }
97 //! Destructor. The memory is freed when the last object referencing the data segment is destroyed
98 virtual ~SegDataBlock()
99 {
100 //DEL cout << " DEBUG-~SegDataBlock() " << hex << mSRef << dec << " NRef()= " << NRef() << endl;
101 Delete();
102 }
103
104
105 //! Adds one segment to the data structure - returns the pointer to the allocated segment.
106 virtual size_t Extend()
107 {
108 T * p = new T[mSRef->segsize];
109 mSRef->dseg.push_back(p);
110 return( mSRef->dseg.size());
111 }
112
113 //! Changes the data segment size and reallocates the memory segments
114 // segsz : Segment size ; nbseg : Number of data segments
115 virtual void SetSize(size_t segsz, size_t nbseg=0)
116 {
117 Delete();
118 mSRef = new SDREF;
119 mSRef->nref = 1;
120 mSRef->segsize = segsz;
121 mSRef->dsid = AnyDataObj::getUniqueId();
122 for(size_t k=0; k<nbseg; k++) Extend();
123 }
124//! Shares the data between two SegDataBlock objects
125 void Share(const SegDataBlock<T>& a)
126 {
127 Delete();
128 mSRef = a.mSRef;
129 mSRef->nref++;
130 }
131
132//! Makes a clone of the data structure and optionaly copie the data
133 void Clone(const SegDBInterface<T> & a, bool cpval=true)
134 {
135 Delete();
136 mSRef = new SDREF;
137 mSRef->nref = 1;
138 mSRef->segsize = a.SegmentSize();
139 for(size_t k=0; k<a.NbSegments(); k++) {
140 Extend();
141 if (cpval) {
142 T * dst = GetSegment(k);
143 const T * src = a.GetSegment(k);
144 memcpy(dst, src, mSRef->segsize*sizeof(T));
145 }
146 }
147 }
148
149
150 //! Return the segment size of the data structure
151 virtual size_t SegmentSize() const { return mSRef->segsize; }
152 //! Return the number of data segments
153 virtual size_t NbSegments() const { return mSRef->dseg.size(); }
154 //! Return the current size of the segmented data structure
155 inline size_t Size() const { return mSRef->segsize*mSRef->dseg.size(); }
156
157 //! Return pointer to data segment \b k
158 virtual T* GetSegment(size_t k) { return mSRef->dseg[k]; }
159 virtual T const * GetSegment(size_t k) const { return mSRef->dseg[k]; }
160
161 //! Return the segment index for element \b i
162 inline size_t SegIndex(size_t i) { return i/mSRef->segsize; }
163 //! Return the offset (in data segment) for element \b i
164 inline size_t EltOffset(size_t i) { return i%mSRef->segsize; }
165
166 //! Return the \b i th element of the segmented data structure
167 inline T& operator()(size_t i) { return *(mSRef->dseg[SegIndex(i)]+EltOffset(i));}
168 //! Return the \b i th element of the data structure
169 inline T& operator()(size_t i) const { return *(mSRef->dseg[SegIndex(i)]+EltOffset(i));}
170 //! Return the \b i th element of the segmented data structure
171 inline T& operator[](size_t i) { return *(mSRef->dseg[SegIndex(i)]+EltOffset(i));}
172 //! Return the \b i th element of the data structure
173 inline T& operator[](size_t i) const { return *(mSRef->dseg[SegIndex(i)]+EltOffset(i));}
174
175
176 //! Return the number of references to the data structure
177 inline size_t NRef() const { return mSRef->nref; }
178
179 //! Equal operator. Set all element values to \b v
180 SegDataBlock<T>& operator = (T const & v)
181 {
182 for(size_t k=0; k<NbSegments(); k++) {
183 T * p = mSRef->dseg[k];
184 for(size_t j=0; j<SegmentSize(); j++) p[j] = v;
185 }
186 return (*this);
187 }
188 //! Equal operator. Clones and copie values from \b a
189 inline SegDataBlock<T>& operator = (const SegDBInterface<T> & a)
190 {
191 Clone(a, true);
192 return (*this);
193 }
194 //! Equal operator. Clones and copie values from \b a
195 inline SegDataBlock<T>& operator = (const SegDataBlock<T> & a)
196 {
197 Clone(a, true);
198 return (*this);
199 }
200
201 //! ASCII formatted output (print)
202 void Print(ostream& os, int lev=0, const char * sep=NULL) const
203 {
204 os << "SegDataBlock< " << typeid(T).name() << "> mSRef= " << hex << mSRef
205 << " NRef=" << dec << NRef() << " DSId= " << DRefId() << endl;
206 os << " ... SegSize= " << SegmentSize() << " NbSeg= " << NbSegments()
207 << " Size= " << Size() << endl;
208 if (sep == NULL) sep = " ";
209 if (lev > 0) {
210 for(size_t k=0; k<NbSegments(); k++) {
211 T * p = mSRef->dseg[k];
212 os << " ..... DataSeg[ " << k << " ] : " << hex << p << dec << endl;
213 if (lev > 1)
214 for(size_t j=0; j<SegmentSize(); j++) os << p[j] << sep;
215 os << endl;
216 }
217 }
218 }
219 //! ASCII formatted output (print) on cout
220 inline void Print(int lev=0, const char * sep=NULL) const
221 {
222 Print(cout, lev, sep);
223 }
224
225 //! Returns the unique object identifier
226 inline uint_8 DRefId() const { return mSRef->dsid; }
227
228protected:
229 void Delete()
230 {
231 if (mSRef == NULL) return;
232 mSRef->nref--;
233 if (mSRef->nref > 0) { mSRef = NULL; return; }
234 //DEL cout << " DEBUG-SegDataBlock::Delete() NbSegments() = " << NbSegments() << endl;
235 for(size_t k=0; k<NbSegments(); k++) {
236 delete[] mSRef->dseg[k];
237 mSRef->dseg[k] = NULL;
238 }
239 delete mSRef;
240 mSRef = NULL;
241 }
242 //! SDREF structure for reference management - for internal use by SegDataBlock
243 typedef struct {
244 size_t nref; //!< Number of references to the data structure
245 uint_8 dsid; //!< Data structure Id - Used by FIO_SegDataBlock
246 std::vector<T *> dseg;
247 size_t segsize;
248 } SDREF;
249
250 SDREF * mSRef; //!< SDREF structure for reference sharing
251};
252
253//! Definition of operator \<\< for ascii formatted output of SegDataBlock
254template<class T>
255inline ostream& operator << (ostream& os, const SegDataBlock<T>& a)
256 { a.Print(os); return(os); }
257
258} // Fin du namespace
259
260#endif
Note: See TracBrowser for help on using the repository browser.