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