HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GA_ATIBlobArray.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: GA_ATIBlobArray.h ( GA Library, C++)
7  *
8  * COMMENTS: Blob Array ATI (Attribute Type Implementation)
9  */
10 
11 #pragma once
12 
13 #ifndef __GA_ATIBlobArray__
14 #define __GA_ATIBlobArray__
15 
16 #include "GA_API.h"
17 #include "GA_Attribute.h"
18 #include "GA_BlobContainer.h"
19 #include "GA_ATIBlob.h"
20 #include "GA_BlobData.h"
21 #include "GA_ArrayDataArray.h"
22 #include "GA_Types.h"
23 
24 #include <UT/UT_StringHolder.h>
25 #include <UT/UT_VectorTypes.h>
26 
27 #include <SYS/SYS_Types.h>
28 
29 #include <stddef.h>
30 
31 
32 class GA_AIFBlobArray;
33 class GA_AIFCompare;
34 class GA_AIFCopyData;
35 class GA_AIFInterp;
36 class GA_AIFMerge;
37 class GA_AttributeType;
38 class GA_Defragment;
39 class GA_IndexMap;
40 class GA_LoadMap;
41 class GA_MergeMap;
42 class GA_SaveMap;
43 class GA_Range;
44 
45 class UT_JSONParser;
46 class UT_JSONWriter;
47 class UT_Options;
48 template <typename T> class UT_Array;
49 
50 
51 /// @brief A simple ATI to store aribtrary "blobs" of data in an attribute
52 ///
53 /// The blob attribute type stores arbitrary blobs (GA_Blob) of data for each
54 /// element in the attribute array. The blobs are stored as reference counted
55 /// shared objects, meaning the blobs may be shared between multiple elements
56 /// of the array. Each blob is referenced by a unique integer handle.
57 ///
58 /// It's also possible to get a list of all the blobs stored by the attribute
59 ///
60 /// By default, the array is filled with NULL pointers.
61 ///
62 /// This class is very simple and only provides a minimal interface. Blob
63 /// attributes are not saved/loaded, and there is minimal access to the blobs.
64 ///
65 /// Users may sub-class from this ATI to create more complicated classes which
66 /// provide alternate interfaces.
67 ///
68 /// This attribute looks for options (GA_Attribute::getOptions())
69 /// - bool blob:stringset (default: true)@n
70 /// This option is queried when merging detail attributes. When true,
71 /// the @b unique blobs from both details will be merged into the resulting
72 /// detail. When false, the resulting detail will only have the blobs from
73 /// the first detail in the merge.
74 ///
76 {
77 public:
78  static void registerType();
80  static const UT_StringHolder &getTypeName()
81  { return theAttributeType->getTypeName(); }
83  static const GA_AttributeType &getType() { return *theAttributeType; }
84 
86  static bool isType(const GA_Attribute *attrib);
88  static GA_ATIBlobArray *cast(GA_Attribute *attrib);
90  static const GA_ATIBlobArray *cast(const GA_Attribute *attrib);
91 
92  static GA_Attribute *create(const GA_IndexMap &index_map,
93  GA_AttributeScope scope,
94  const UT_StringHolder &name,
95  const GA_AttributeOptions *attribute_options=NULL);
96  static GA_Attribute *create(const GA_IndexMap &index_map,
97  const UT_StringHolder &name)
98  {
99  return create(index_map, GA_SCOPE_PUBLIC, name);
100  }
101 
103  const GA_IndexMap &index_map,
104  GA_AttributeScope scope,
105  const UT_StringHolder &name,
106  int tuple_size);
107  virtual ~GA_ATIBlobArray();
108 
109  /// Report approximate memory usage
110  virtual int64 getMemoryUsage(bool inclusive) const;
111 
112  virtual void countMemory(UT_MemoryCounter &counter, bool inclusive) const;
113 
114  /// @{
115  /// Interface for defragmentation
116  virtual void defragment(const GA_Defragment &defrag)
117  { myHandles.defragment(defrag); }
118  /// @}
119 
121  { return myHandles.findMaximumArrayLength(); }
122 
123  /// Get the tuple size
124  int getTupleSize() const
125  { return myHandles.getTupleSize(); }
126 
127  /// Return the entries in the blob container
128  int entries() const
129  { return myBlobs.entries(); }
130 
131  /// Return the maximum index of any blob in the container. This may be
132  /// more than the number of blobs in the container. If the maximum index
133  /// is less than 0, there are no blobs in the container.
135  { return myBlobs.getMaximumIndex(); }
136 
137  /// Return the capacity of the blob container
138  int capacity() const
139  { return myBlobs.capacity(); }
140 
141  /// Look up a blob handle by offset.
142  void getBlobIndex(UT_Array<GA_BlobIndex> &indices, GA_Offset offset) const;
143 
144  /// Store a new blob_index at the given offset
145  bool setBlobIndex(const UT_Array<GA_BlobIndex> &indices,
146  GA_Offset offset);
147 
148  /// Get the blob associated with a given offset into the array
150  GA_Offset offset) const
151  {
153  getBlobIndex(indices, offset);
154 
155  blobs.clear();
156  blobs.setCapacityIfNeeded(indices.entries());
157  for (int i = 0; i < indices.entries(); i++)
158  blobs.append(lookupBlob(indices(i)));
159  }
160 
161  /// Store a new blob at the given offset
162  bool setBlob(const UT_Array<GA_BlobRef> &blobs,
163  GA_Offset offset);
164 
165  /// Replace a blob in the blob container with a new blob value
166  bool replaceBlob(GA_BlobIndex handle,
167  const GA_BlobRef &blob);
168 
169 
170  /// Look up a blob given its handle
172  { return myBlobs.getBlob(handle); }
173 
174  /// Lookup a blob given an ordered index
176  { return myBlobs.getOrderedBlob(idx); }
177 
178  /// This method will "compact" the attribute container, possibly changing
179  /// all the handles in the attribute data.
180  virtual void compactStorage();
181 
182  /// Get a measure of the vacancy entropy of the storage container. This
184  { return myBlobs.getOccupancy(); }
185 
186  /// Adding blobs is thread-safe, so we're only subject to GA_DataArray
187  /// limitations.
189  { return WRITE_CONCURRENCE_PAGE; }
190 
191  virtual const GA_AIFBlobArray *getAIFBlobArray() const { return myAIFBlobArray; }
192  virtual const GA_AIFMerge *getAIFMerge() const { return myAIFMerge; }
193  virtual const GA_AIFCompare *getAIFCompare() const { return myAIFCompare;}
194  virtual const GA_AIFCopyData *getAIFCopyData() const{ return myAIFCopyData;}
195  virtual const GA_AIFInterp *getAIFInterp() const { return 0; }
196 
197  /// Save blobs to a JSON stream.
198  /// This method can be called by sub-classes to save blob data to a JSON
199  /// stream. Since the GA_ATIBlob class doesn't provide an GA_AIFJSON
200  /// interface, data is not saved/loaded by default.
201  ///
202  /// @param w The JSON writer
203  /// @param s The save map options
204  /// @param blobtoken The token used to identify the blob data
205  bool jsonSave(UT_JSONWriter &w,
206  const GA_SaveMap &s,
207  const char *blobtoken = "data") const;
208 
209  /// Load blobs from a JSON stream. This method can be called by
210  /// sub-classes to load their data from a JSON stream. The class must
211  /// provide a GA_BlobDataLoader class which is used to create and load new
212  /// blob data.
213  ///
214  /// @param p The JSON parser
215  /// @param blobloader A class to create and load blobs
216  /// @param load Load options
217  /// @param blobtoken The token used to identify the blob data
218  bool jsonLoad(UT_JSONParser &p,
219  const GA_BlobDataLoader &blobloader,
220  const GA_LoadMap &load,
221  const char *blobtoken = "data");
222 
223  /// Convenience function to extract all the blobs (and their handles)
224  /// The string handles are guaranteed to be in ascending order, but
225  /// may or may not be contiguous.
227  UT_IntArray &handles) const
228  {
229  return myBlobs.extractBlobs(blobs, handles);
230  }
231 
232  /// Grow or shrink the array size
233  virtual bool setArraySize(GA_Offset new_size);
234 
235  /// Return the array size for a given offset
236  virtual exint arraySize(GA_Offset item) const;
237 
238  /// Try to compress data pages
239  virtual void tryCompressAllPages(
240  GA_Offset start_offset = GA_Offset(0),
241  GA_Offset end_offset = GA_INVALID_OFFSET);
242  /// Harden data pages
243  virtual void hardenAllPages(
244  GA_Offset start_offset = GA_Offset(0),
245  GA_Offset end_offset = GA_INVALID_OFFSET);
246 
247  /// Returns true iff that is an attribute whose content can be copied
248  /// from this without any type conversions. This is important to
249  /// avoid reallocation of an attribute if its storage type,
250  /// including tuple size, matches the source attribute exactly.
251  virtual bool matchesStorage(const GA_Attribute *that) const
252  {
253  if (!GA_Attribute::matchesStorage(that))
254  return false;
255  const GA_ATIBlobArray *thatn = UTverify_cast<const GA_ATIBlobArray *>(that);
256  if (getTupleSize() != thatn->getTupleSize())
257  return false;
258  return true;
259  }
260 
261  /// This replaces the entirety of this attribute's content and non-
262  /// storage metadata (except the name) with that of the src attribute.
263  /// matchesStorage(src) should already return true.
264  /// This is primarily for use by GA_AttributeSet::replace().
265  /// NOTE: The internal content sizes may not match exactly if the
266  /// attribute type may overallocate, but the sizes should be such
267  /// that any real data will fit in the destination, so be careful
268  /// and deal with the myTailInitialize flag appropriately if
269  /// any extra elements aren't equal to the default.
270  virtual void replace(const GA_Attribute &src);
271 
272 protected: // Methods
273  /// Blob attributes need each element to properly destruct for accurate
274  /// reference counting.
275  virtual bool needDestruction() const;
276 
277  /// Callback method to destruct an offset.
278  virtual void destructElement(GA_Offset offset);
279 
280  /// Create a new ATIBlob attribute. Sub-classes must implement this.
281  virtual GA_Attribute *doClone(const GA_IndexMap &index_map,
282  const UT_StringHolder &name) const;
283 
284  /// @{ GA_AIFMerge
285  /// Base class implementation of GA_AIFMerge::destroyDestination()
286  void mergeDestroyDestination(const GA_MergeMap &map,
287  GA_Attribute *dattrib) const;
288  /// Base class implementation of GA_AIFMerge::addDestination()
289  GA_Attribute *mergeAddDestination(const GA_MergeMap &map,
290  GA_Attribute *dattrib) const;
291  /// Base class implementation of GA_AIFMerge::growArray()
292  void mergeGrowArray(const GA_MergeMap &map, const GA_ATIBlobArray &s);
293 
294  /// Base class implementation of GA_AIFMerge::copyArray()
295  bool mergeAppendData(const GA_MergeMap &map,
296  const GA_Attribute *sattrib);
297  /// @}
298 
299  /// @{
300  /// Methods to implement copying of data for AIFCopyData
301  bool copyData(GA_Offset di,
302  const GA_ATIBlobArray *s,
303  GA_Offset si);
304  bool copyData(const GA_Range &di,
305  const GA_ATIBlobArray *s,
306  const GA_Range &si);
307  /// @}
308 
309  /// @{
310  /// The addBlobBuffer()/delBlobBuffer() methods are added solely for the
311  /// corresponding methods in GA_AIFBlob.
312  GA_BlobIndex addBlobReference(const GA_BlobRef &blob);
313  void delBlobReference(GA_BlobIndex handle);
314  /// @}
315 
316  /// @{
317  /// Interface used by AIFCompare. By default, this will use the blob key
318  /// comparison to determine equality.
319  virtual bool isEqual(GA_Offset offset,
320  const GA_ATIBlobArray &b, GA_Offset b_offset) const;
321  virtual bool isEqual(const GA_Range & range,
322  const GA_ATIBlobArray &b, const GA_Range &b_range) const;
323  /// @}
324 
325 protected: // Data
326  /// Array of handles. The default value is []
327  /// This is protected for convenience to sub-classes.
329 
330  /// Blob references. This is protected for convenience to sub-classes.
332 
333 private:
334  /// Load up an array of blob
335  bool jsonLoadBlobs(UT_JSONParser &p,
336  const GA_LoadMap &load,
337  UT_Array<GA_BlobRef> &blobs,
338  const GA_BlobDataLoader &blobloader);
339 
340  /// AIF Merge interface
341  static GA_AIFBlobArray *myAIFBlobArray;
342  static GA_AIFMerge *myAIFMerge;
343  static GA_AIFCopyData *myAIFCopyData;
344  static GA_AIFCompare *myAIFCompare;
345 
346  static const GA_AttributeType *theAttributeType;
347 
348  /// @cond INTERNAL_DOX
349  friend class ga_BlobArrayBlob;
350  friend class ga_BlobArrayMerge;
351  friend class ga_BlobArrayCopyData;
352  friend class ga_BlobArrayCompare;
353  /// @endcond
354 };
355 
356 // NOTE: It may seem strange to include GA_ATIStringArray.h here,
357 // but GA_ATIBlobArray::isType() and cast() need GA_ATIStringArray::isType(),
358 // and GA_ATIStringArray inherits from GA_ATIBlobArray, so
359 // GA_ATIBlobArray::isType() and cast() are defined in GA_ATIStringArray.h
360 // below the class.
361 #include "GA_ATIStringArray.h"
362 
363 #endif
static SYS_FORCE_INLINE const UT_StringHolder & getTypeName()
GLdouble s
Definition: glew.h:1390
A class to manage an ordered array which has fixed offset handles.
Definition: GA_IndexMap.h:63
GA_BlobContainer myBlobs
Blob references. This is protected for convenience to sub-classes.
virtual void defragment(const GA_Defragment &defrag)
GLenum GLint * range
Definition: glew.h:3500
Definition of a geometry attribute.
Definition: GA_Attribute.h:190
int entries() const
Return the entries in the blob container.
GLenum src
Definition: glew.h:2410
GLuint const GLchar * name
Definition: glew.h:1814
Used to pass options and map offset values during saving.
Definition: GA_SaveMap.h:48
int capacity() const
Return the capacity of the blob container.
int getTupleSize() const
Size of the AIFTuple, if it exists. If it doesn't, 1.
GA_BlobIndex getMaximumIndex() const
virtual const GA_AIFBlobArray * getAIFBlobArray() const
Return the attribute's blob array interface or NULL.
GA_ArrayDataArray myHandles
virtual WriteConcurrence getSupportedWriteConcurrence() const
Attribute Interface for accessing generic blob data.
The merge map keeps track of information when merging details.
Definition: GA_MergeMap.h:53
JSON reader class which handles parsing of JSON or bJSON files.
Definition: UT_JSONParser.h:75
virtual bool setArraySize(GA_Offset size)=0
#define GA_API
Definition: GA_API.h:12
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:32
SYS_FORCE_INLINE TO_T UTverify_cast(FROM_T from)
Definition: UT_Assert.h:208
virtual void countMemory(UT_MemoryCounter &counter, bool inclusive) const =0
Standard user attribute level.
Definition: GA_Types.h:145
virtual int64 getMemoryUsage(bool inclusive) const =0
virtual bool matchesStorage(const GA_Attribute *that) const
Definition: GA_Attribute.h:728
static SYS_FORCE_INLINE const GA_AttributeType & getType()
virtual void tryCompressAllPages(GA_Offset start_offset=GA_Offset(0), GA_Offset end_offset=GA_INVALID_OFFSET)=0
An array of array of numbers with various storage types.
#define GA_INVALID_OFFSET
Definition: GA_Types.h:674
A range of elements in an index-map.
Definition: GA_Range.h:42
GA_Size GA_Offset
Definition: GA_Types.h:637
long long int64
Definition: SYS_Types.h:111
GA_AttributeScope
Definition: GA_Types.h:139
virtual bool needDestruction() const
Methods which can be overridden from GA_Attribute.
exint findMaximumArrayLength() const
Utility class to load blob data from a JSON stream.
Definition: GA_ATIBlob.h:58
virtual void replace(const GA_Attribute &src)=0
Attribute Interface for merging attribute data between details.
Definition: GA_AIFMerge.h:56
UT_IndexedHashMapItemId GA_BlobIndex
int64 exint
Definition: SYS_Types.h:120
GLuint GLuint GLsizei GLenum const void * indices
Definition: glew.h:1253
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
GLubyte GLubyte GLubyte GLubyte w
Definition: glew.h:1890
virtual const GA_AIFInterp * getAIFInterp() const
Return the attribute's interpolation interface or NULL.
fpreal getStorageOccupancy()
Get a measure of the vacancy entropy of the storage container. This.
Attribute Interface class to perform comparisons on attributes.
Definition: GA_AIFCompare.h:27
Options during loading.
Definition: GA_LoadMap.h:42
virtual const GA_AIFMerge * getAIFMerge() const
Return the attribute's merge interface or NULL.
Defragmentation of IndexMaps.
Definition: GA_Defragment.h:45
GA_BlobRef getOrderedBlob(exint idx) const
Lookup a blob given an ordered index.
GLuint GLuint GLsizei GLenum type
Definition: glew.h:1253
exint entries() const
Alias of size(). size() is preferred.
Definition: UT_Array.h:453
GLdouble GLdouble GLdouble b
Definition: glew.h:9122
GLfloat GLfloat p
Definition: glew.h:16321
double fpreal
Definition: SYS_Types.h:276
A map of string to various well defined value types.
Definition: UT_Options.h:42
GA_BlobRef lookupBlob(GA_BlobIndex handle) const
Look up a blob given its handle.
virtual const GA_AIFCompare * getAIFCompare() const
Return the attribute's comparison interface or NULL.
void getBlob(UT_Array< GA_BlobRef > &blobs, GA_Offset offset) const
Get the blob associated with a given offset into the array.
A simple ATI to store aribtrary "blobs" of data in an attribute.
GLuint counter
Definition: glew.h:2740
virtual bool matchesStorage(const GA_Attribute *that) const
static GA_Attribute * create(const GA_IndexMap &index_map, const UT_StringHolder &name)
Concurrent writes to separate pages supported.
Definition: GA_Attribute.h:358
virtual void compactStorage()
exint append(void)
Definition: UT_Array.h:95
void setCapacityIfNeeded(exint mincapacity)
Definition: UT_Array.h:408
virtual void destructElement(GA_Offset offset)
Callback invoked if needsDestruction() returns true.
Attribute Interface class to copy attribute data.
void clear()
Resets list to an empty list.
Definition: UT_Array.h:519
virtual const GA_AIFCopyData * getAIFCopyData() const
Return the attribute's copy interface or NULL.
virtual void hardenAllPages(GA_Offset start_offset=GA_Offset(0), GA_Offset end_offset=GA_INVALID_OFFSET)=0
int getTupleSize() const
Get the tuple size.
int extractBlobs(UT_Array< GA_BlobRef > &blobs, UT_IntArray &handles) const
Container to store blobs of arbitrary data for attributes.
GLintptr offset
Definition: glew.h:1682