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

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

1/ Simplification de la classe gestionnairee PPersist ObjFile<T> (objfio.h)
2/ Ajout DECL_TEMP_SPEC ds ppftpointerio.h
3/ Nom specifique pour methode SegDBInterface::GetSegment() const devenu
SegDBInterface::GetCstSegment() const pour eviter l'appel a la methode non const
et adapatation classes derivees (segdatablock.h et swsegdb.h)
4/ Ajout SkipToNextObjet() ds PInPersist::ReadObject() (ppersist.cc) et protection contre pointeur NULL -> new DVList pour la lecture PPersist de DVList

Reza - 27 Avril 2005

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