Free Electron
RecordArraySB.h
Go to the documentation of this file.
1 /* Copyright (C) 2003-2021 Free Electron Organization
2  Any use of this software requires a license. If a valid license
3  was not distributed with this file, visit freeelectron.org. */
4 
5 /** @file */
6 
7 #ifndef __data_RecordArraySB_h__
8 #define __data_RecordArraySB_h__
9 
10 namespace fe
11 {
12 
13 struct hash_sb_pointer
14 { FE_UWORD operator()(const void *pV) const
15  { return reinterpret_cast<FE_UWORD>(pV); } };
16 
17 struct eq_sb_pointer
18 { bool operator()(void *pV1, void *pV2) const
19  { return pV1 == pV2; } };
20 
21 #if 1
22 typedef HashMap< void *,
23  IWORD,
24  hash_sb_pointer,
25  eq_sb_pointer> t_sb_map;
26 #else
27 typedef std::map< void *, IWORD > t_sb_map;
28 #endif
29 
30 
31 /** @brief Homogeneous collection of Records
32 
33  @ingroup data
34 
35  An array of Records, or more precisely an array of state block pointers
36  all pointing to state blocks of the same layout. Therefore only a single
37  reference to the layout itself is stored. Therefore this record array
38  object consumes less memory than an array of record objects.
39  */
40 class FE_DL_EXPORT RecordArraySB : public Counted
41 {
42  public:
43  RecordArraySB(void);
44  RecordArraySB(sp<LayoutSB> spLayout);
45  RecordArraySB(sp<LayoutSB> spLayout, FE_UWORD aCount);
46  RecordArraySB(const RecordArraySB &other);
47 virtual ~RecordArraySB(void);
48 
49  RecordArraySB &operator=(const RecordArraySB &other);
50  // /** Return the state block at the given index. */
51  //void *operator[](IWORD index);
52  FE_UWORD idr(IWORD index);
53  /** Return the length of the array. */
54  IWORD length(void);
55  /** Return the Layout. */
56  sp<Layout> layout(void);
57  /** Return a raw pointer to the Layout. Mainly intended for Accessor
58  for speed. */
59  //LayoutSB *rawLayout(void) const;
60  /** Add the given record to the array. If the record array already
61  has records and the Layout is different than for @em record
62  the record will not be added and false will be returned.
63  On success true is returned and if @em index is not NULL the index
64  of the added record is return in @em index . */
65  bool add(const RecordSB &record, IWORD *index = NULL);
66 
67  bool add(sp<RecordArraySB> spRA, IWORD start, IWORD size);
68 
69  bool addCovert(const RecordSB &record, IWORD *index = NULL){return false;}
70  bool addCovert(sp<RecordArraySB> spRA, IWORD start, IWORD size){return false;}
71 
72  void enableDuplicates(bool a_bool);
73 
74  /** create and add a record of an already set Layout. This avoids
75  the overhead of checking for duplicates. */
76  bool addCreate(void);
77 
78  /** Remove the given record from the array. On success return
79  true and if @em index is provided return the index of the removed
80  record. If the record is not in the array return false. */
81  bool remove(const RecordSB &record, IWORD *index = NULL);
82 
83  // dummy due to AV
84  bool removeCovert(const RecordSB &record,IWORD *index=NULL) { return false; }
85  void removeCovert(IWORD index) {}
86  void bind(sp<RecordGroup> a_spRecordGroup) {}
87 
88  /** Return the record at the given index. */
89  RecordSB getRecord(IWORD index);
90  /// Return a non-persistent record for the given index
91  WeakRecordSB getWeakRecord(IWORD index);
92  /** Clear the record array. */
93  void clear(void);
94  /** Return true if @em record is in the record array. Otherwise return
95  false. */
96  bool find(const RecordSB &record);
97 
98  void set(WeakRecordSB &record, IWORD index);
99  void set(RecordSB &record, IWORD index);
100 
101  void setLayout(const sp<LayoutSB>& rspLayout);
102 
103  /// @brief Remove any invalid weak references
104  void prune(void);
105 
106  /** @internal
107 
108  @brief Choose weak referencing
109 
110  This should only be set by RecordGroup at
111  construction. */
112  void setWeak(BWORD weak);
113 
114  /// @brief Return TRUE if using weak referencing
115  BWORD isWeak(void) const { return m_weak; }
116 
117  /** Remove record at given index. The array is kept
118  contiguous by moving the last element into the
119  the given index after removal. Therefore, in
120  an iteration that involves deletion it is best
121  to iterate backwards through the array. */
122  void remove(IWORD index);
123 
124  template <class T>
125  T &accessAttribute(FE_UWORD aLocator, FE_UWORD aIndex) const;
126  private:
127  /** Return the state block at the given index. */
128  void *data(IWORD index) const;
129  private:
130  void grow(void);
131  void copy(const RecordArraySB &other);
132  void acquireSB(IWORD index);
133  void releaseSB(IWORD index);
134 
135  I32 readSerialNumber(IWORD index) const;
136 
137  void trackBlock(U32 index);
138  void untrackBlock(U32 index);
139 
140  private:
141  sp<LayoutSB> m_spLayout;
142  void **m_ppSB;
143  IWORD *m_pSN;
144  IWORD m_allocated;
145  IWORD m_used;
146  BWORD m_weak;
147  I32 m_serialOffset;
148  bool m_duplicates;
149  t_sb_map m_sb_map;
150 
151 #if FE_COUNTED_TRACK
152  public:
153 const String& name(void) const
154  { return m_spLayout.isValid()?
155  m_spLayout->name(): Counted::name(); }
156 const String verboseName(void) const
157  { return "RecordArray " +
158  String(m_weak? "(weak) ": "") + name(); }
159 #endif
160 };
161 
162 template <class T>
163 inline T &RecordArraySB::accessAttribute(FE_UWORD aLocator, FE_UWORD aIndex) const
164 {
165 #if FE_CODEGEN<=FE_DEBUG
166  return *((T *)((char *)(data(aIndex)) + m_spLayout->offsetTable()[aLocator]));
167 #else
168  return *((T *)((char *)(data(aIndex)) + m_spLayout.raw()->offsetTable()[aLocator]));
169 #endif
170 }
171 
172 class PtrRecordArraySBInfo : public BaseType::Info
173 {
174  public:
175 virtual IWORD output(std::ostream &ostrm, void *instance, t_serialMode mode);
176 virtual void input(std::istream &istrm, void *instance, t_serialMode mode);
177 virtual IWORD iosize(void);
178 virtual bool getConstruct(void);
179 virtual void construct(void *instance);
180 virtual void destruct(void *instance);
181 };
182 
183 inline void RecordArraySB::setWeak(BWORD weak)
184 {
185  m_weak = weak;
186 #if FE_COUNTED_TRACK
187  //* propagate name change
188  sp<RecordArraySB> spRA(this);
189 #endif
190 }
191 
192 inline void RecordArraySB::set(WeakRecordSB &record, IWORD index)
193 {
194  record.set(m_ppSB[index]);
195 }
196 
197 inline void RecordArraySB::set(RecordSB &record, IWORD index)
198 {
199  record.set(m_ppSB[index]);
200 }
201 
202 #if 0
203 inline LayoutSB *RecordArraySB::rawLayout(void) const
204 {
205  return m_spLayout.raw();
206 }
207 #endif
208 
209 #if 0
210 inline void *RecordArraySB::operator[](IWORD index)
211 {
212  return m_ppSB[index];
213 }
214 #endif
215 
216 inline IWORD RecordArraySB::length(void)
217 {
218  return m_used;
219 }
220 
222 {
223  return m_spLayout;
224 }
225 
227 {
228  RecordSB record;
229  void* pSB=data(index);
230  if(pSB)
231  {
232  record.set(pSB);
233  }
234  return record;
235 }
236 
238 {
239  WeakRecordSB record;
240  void* pSB=data(index);
241  if(pSB)
242  {
243  record.set(pSB);
244  }
245  return record;
246 }
247 
248 inline void RecordArraySB::acquireSB(IWORD index)
249 {
250  if(!m_weak)
251  {
252  FE_SB_TO_HDR(m_ppSB[index])->m_pStore->acquireSB(m_ppSB[index]);
253  }
254  trackBlock(index);
255 }
256 
257 inline void RecordArraySB::releaseSB(IWORD index)
258 {
259  untrackBlock(index);
260  if(!m_weak)
261  {
262  FE_SB_TO_HDR(m_ppSB[index])->m_pStore->releaseSB(getRecord(index));
263  }
264 }
265 
266 inline I32 RecordArraySB::readSerialNumber(IWORD index) const
267 {
268  return (m_serialOffset>=0 && m_ppSB[index])?
269  *((I32 *)((char *)(m_ppSB[index]) + m_serialOffset)): -1;
270 }
271 
272 inline void* RecordArraySB::data(IWORD index) const
273 {
274 #if FE_CODEGEN<=FE_DEBUG
275  if(index >= m_used || index < 0)
276  {
277  feX("fe::RecordArray::data","index out of range");
278  }
279 #endif
280 #if 0
281  if(m_weak)
282  {
283  feLog("RecordArray::data %d SN %d vs %d\n",
284  index,m_pSN[index],readSerialNumber(index));
285  }
286 #endif
287 
288  if(m_weak && m_pSN[index]>=0 && m_pSN[index]!=readSerialNumber(index))
289  {
290  feLog("RecordArray::data weak element %d is not valid (%d vs %d)\n",
291  index,m_pSN[index],readSerialNumber(index));
292 #if FE_COUNTED_TRACK
293  feLog(" name \"%s\"\n",name().c_str());
294 #endif
295 
296  m_ppSB[index]=NULL;
297  return NULL;
298  }
299  return m_ppSB[index];
300 }
301 
302 inline FE_UWORD RecordArraySB::idr(IWORD index)
303 {
304  return reinterpret_cast<FE_UWORD>(data(index));
305 }
306 
307 inline void RecordArraySB::untrackBlock(U32 index)
308 {
309 #if FE_COUNTED_TRACK
310  untrackReference(FE_SB_TO_HDR(m_ppSB[index]),this);
311 #endif
312 }
313 
314 inline void RecordArraySB::trackBlock(U32 index)
315 {
316 #if FE_COUNTED_TRACK
317  String blockname;
318  blockname.sPrintf("block:%d %s",index,name().c_str());
319  trackReference(FE_SB_TO_HDR(m_ppSB[index]),this,"RecordArray");
320 #endif
321 }
322 
323 };
324 
325 #endif /* __data_RecordArraySB_h__ */
sp< Layout > layout(void)
Return the Layout.
Definition: RecordArraySB.h:221
FE_UWORD idr(IWORD index)
Return the state block at the given index.
Definition: RecordArraySB.h:302
Heap-based support for classes participating in fe::ptr <>
Definition: Counted.h:35
kernel
Definition: namespace.dox:3
IWORD length(void)
Return the length of the array.
Definition: RecordArraySB.h:216
void set(void *datablock)
Set the state block.
Definition: RecordSB.h:194
String & sPrintf(const char *fmt,...)
Populate the string in the manner of sprintf().
Definition: String.cc:529
Automatically reference-counted string container.
Definition: String.h:128
Reference to an instance of a Layout.
Definition: RecordSB.h:35
void * data(IWORD index) const
Return the state block at the given index.
Definition: RecordArraySB.h:272
RecordSB getRecord(IWORD index)
Return the record at the given index.
Definition: RecordArraySB.h:226
Intrusive Smart Pointer.
Definition: src/core/ptr.h:53
Record "type" definition.
Definition: LayoutSB.h:32
void setWeak(BWORD weak)
Choose weak referencing.
Definition: RecordArraySB.h:183
Homogeneous collection of Records.
Definition: RecordArraySB.h:40
BWORD isWeak(void) const
Return TRUE if using weak referencing.
Definition: RecordArraySB.h:115
void set(void *datablock)
Set the state block.
Definition: WeakRecordSB.h:197
Non-persistent reference to an instance of a Layout.
Definition: WeakRecordSB.h:17
WeakRecordSB getWeakRecord(IWORD index)
Return a non-persistent record for the given index.
Definition: RecordArraySB.h:237