HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros 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 
154  getBlobIndex(indices, offset);
155  blobs.clear();
156  for (int i = 0; i < indices.entries(); i++)
157  blobs.append(lookupBlob(indices(i)));
158  }
159 
160  /// Store a new blob at the given offset
161  bool setBlob(const UT_Array<GA_BlobRef> &blobs,
162  GA_Offset offset);
163 
164  /// Replace a blob in the blob container with a new blob value
165  bool replaceBlob(GA_BlobIndex handle,
166  const GA_BlobRef &blob);
167 
168 
169  /// Look up a blob given its handle
171  { return myBlobs.getBlob(handle); }
172 
173  /// Lookup a blob given an ordered index
175  { return myBlobs.getOrderedBlob(idx); }
176 
177  /// This method will "compact" the attribute container, possibly changing
178  /// all the handles in the attribute data.
179  virtual void compactStorage();
180 
181  /// Get a measure of the vacancy entropy of the storage container. This
183  { return myBlobs.getOccupancy(); }
184 
185  /// Adding blobs is thread-safe, so we're only subject to GA_DataArray
186  /// limitations.
188  { return WRITE_CONCURRENCE_PAGE; }
189 
190  virtual const GA_AIFBlobArray *getAIFBlobArray() const { return myAIFBlobArray; }
191  virtual const GA_AIFMerge *getAIFMerge() const { return myAIFMerge; }
192  virtual const GA_AIFCompare *getAIFCompare() const { return myAIFCompare;}
193  virtual const GA_AIFCopyData *getAIFCopyData() const{ return myAIFCopyData;}
194  virtual const GA_AIFInterp *getAIFInterp() const { return 0; }
195 
196  /// Save blobs to a JSON stream.
197  /// This method can be called by sub-classes to save blob data to a JSON
198  /// stream. Since the GA_ATIBlob class doesn't provide an GA_AIFJSON
199  /// interface, data is not saved/loaded by default.
200  ///
201  /// @param w The JSON writer
202  /// @param s The save map options
203  /// @param blobtoken The token used to identify the blob data
204  bool jsonSave(UT_JSONWriter &w,
205  const GA_SaveMap &s,
206  const char *blobtoken = "data") const;
207 
208  /// Load blobs from a JSON stream. This method can be called by
209  /// sub-classes to load their data from a JSON stream. The class must
210  /// provide a GA_BlobDataLoader class which is used to create and load new
211  /// blob data.
212  ///
213  /// @param p The JSON parser
214  /// @param blobloader A class to create and load blobs
215  /// @param load Load options
216  /// @param blobtoken The token used to identify the blob data
217  bool jsonLoad(UT_JSONParser &p,
218  const GA_BlobDataLoader &blobloader,
219  const GA_LoadMap &load,
220  const char *blobtoken = "data");
221 
222  /// Convenience function to extract all the blobs (and their handles)
223  /// The string handles are guaranteed to be in ascending order, but
224  /// may or may not be contiguous.
226  UT_IntArray &handles) const
227  {
228  return myBlobs.extractBlobs(blobs, handles);
229  }
230 
231  /// Grow or shrink the array size
232  virtual bool setArraySize(GA_Offset new_size);
233 
234  /// Return the array size for a given offset
235  virtual exint arraySize(GA_Offset item) const;
236 
237  /// Try to compress data pages
238  virtual void tryCompressAllPages(
239  GA_Offset start_offset = GA_Offset(0),
240  GA_Offset end_offset = GA_INVALID_OFFSET);
241  /// Harden data pages
242  virtual void hardenAllPages(
243  GA_Offset start_offset = GA_Offset(0),
244  GA_Offset end_offset = GA_INVALID_OFFSET);
245 
246  /// Returns true iff that is an attribute whose content can be copied
247  /// from this without any type conversions. This is important to
248  /// avoid reallocation of an attribute if its storage type,
249  /// including tuple size, matches the source attribute exactly.
250  virtual bool matchesStorage(const GA_Attribute *that) const
251  {
252  if (!GA_Attribute::matchesStorage(that))
253  return false;
254  const GA_ATIBlobArray *thatn = UTverify_cast<const GA_ATIBlobArray *>(that);
255  if (getTupleSize() != thatn->getTupleSize())
256  return false;
257  return true;
258  }
259 
260  /// This replaces the entirety of this attribute's content and non-
261  /// storage metadata (except the name) with that of the src attribute.
262  /// matchesStorage(src) should already return true.
263  /// This is primarily for use by GA_AttributeSet::replace().
264  /// NOTE: The internal content sizes may not match exactly if the
265  /// attribute type may overallocate, but the sizes should be such
266  /// that any real data will fit in the destination, so be careful
267  /// and deal with the myTailInitialize flag appropriately if
268  /// any extra elements aren't equal to the default.
269  virtual void replace(const GA_Attribute &src);
270 
271 protected: // Methods
272  /// Blob attributes need each element to properly destruct for accurate
273  /// reference counting.
274  virtual bool needDestruction() const;
275 
276  /// Callback method to destruct an offset.
277  virtual void destructElement(GA_Offset offset);
278 
279  /// Create a new ATIBlob attribute. Sub-classes must implement this.
280  virtual GA_Attribute *doClone(const GA_IndexMap &index_map,
281  const UT_StringHolder &name) const;
282 
283  /// @{ GA_AIFMerge
284  /// Base class implementation of GA_AIFMerge::destroyDestination()
285  void mergeDestroyDestination(const GA_MergeMap &map,
286  GA_Attribute *dattrib) const;
287  /// Base class implementation of GA_AIFMerge::addDestination()
288  GA_Attribute *mergeAddDestination(const GA_MergeMap &map,
289  GA_Attribute *dattrib) const;
290  /// Base class implementation of GA_AIFMerge::growArray()
291  void mergeGrowArray(const GA_MergeMap &map, const GA_ATIBlobArray &s);
292 
293  /// Base class implementation of GA_AIFMerge::copyArray()
294  bool mergeAppendData(const GA_MergeMap &map,
295  const GA_Attribute *sattrib);
296  /// @}
297 
298  /// @{
299  /// Methods to implement copying of data for AIFCopyData
300  bool copyData(GA_Offset di,
301  const GA_ATIBlobArray *s,
302  GA_Offset si);
303  bool copyData(const GA_Range &di,
304  const GA_ATIBlobArray *s,
305  const GA_Range &si);
306  /// @}
307 
308  /// @{
309  /// The addBlobBuffer()/delBlobBuffer() methods are added solely for the
310  /// corresponding methods in GA_AIFBlob.
311  GA_BlobIndex addBlobReference(const GA_BlobRef &blob);
312  void delBlobReference(GA_BlobIndex handle);
313  /// @}
314 
315  /// @{
316  /// Interface used by AIFCompare. By default, this will use the blob key
317  /// comparison to determine equality.
318  virtual bool isEqual(GA_Offset offset,
319  const GA_ATIBlobArray &b, GA_Offset b_offset) const;
320  virtual bool isEqual(const GA_Range & range,
321  const GA_ATIBlobArray &b, const GA_Range &b_range) const;
322  /// @}
323 
324 protected: // Data
325  /// Array of handles. The default value is []
326  /// This is protected for convenience to sub-classes.
328 
329  /// Blob references. This is protected for convenience to sub-classes.
331 
332 private:
333  /// Load up an array of blob
334  bool jsonLoadBlobs(UT_JSONParser &p,
335  const GA_LoadMap &load,
336  UT_Array<GA_BlobRef> &blobs,
337  const GA_BlobDataLoader &blobloader);
338 
339  /// AIF Merge interface
340  static GA_AIFBlobArray *myAIFBlobArray;
341  static GA_AIFMerge *myAIFMerge;
342  static GA_AIFCopyData *myAIFCopyData;
343  static GA_AIFCompare *myAIFCompare;
344 
345  static const GA_AttributeType *theAttributeType;
346 
347  /// @cond INTERNAL_DOX
348  friend class ga_BlobArrayBlob;
349  friend class ga_BlobArrayMerge;
350  friend class ga_BlobArrayCopyData;
351  friend class ga_BlobArrayCompare;
352  /// @endcond
353 };
354 
355 // NOTE: It may seem strange to include GA_ATIStringArray.h here,
356 // but GA_ATIBlobArray::isType() and cast() need GA_ATIStringArray::isType(),
357 // and GA_ATIStringArray inherits from GA_ATIBlobArray, so
358 // GA_ATIBlobArray::isType() and cast() are defined in GA_ATIStringArray.h
359 // below the class.
360 #include "GA_ATIStringArray.h"
361 
362 #endif
363 
static SYS_FORCE_INLINE const UT_StringHolder & getTypeName()
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)
Definition of a geometry attribute.
Definition: GA_Attribute.h:189
int entries() const
Return the entries in the blob container.
GLsizei GLenum const void * indices
Definition: glcorearb.h:405
GLenum GLint * range
Definition: glcorearb.h:1924
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:72
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
virtual void countMemory(UT_MemoryCounter &counter, bool inclusive) const =0
Standard user attribute level.
Definition: GA_Types.h:127
virtual int64 getMemoryUsage(bool inclusive) const =0
virtual bool matchesStorage(const GA_Attribute *that) const
Definition: GA_Attribute.h:680
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
png_uint_32 i
Definition: png.h:2877
An array of array of numbers with various storage types.
#define GA_INVALID_OFFSET
Definition: GA_Types.h:654
A range of elements in an index-map.
Definition: GA_Range.h:42
GA_Size GA_Offset
Definition: GA_Types.h:617
long long int64
Definition: SYS_Types.h:106
GA_AttributeScope
Definition: GA_Types.h:121
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:115
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
GLintptr offset
Definition: glcorearb.h:664
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
GLuint const GLchar * name
Definition: glcorearb.h:785
SYS_FORCE_INLINE TO_T UTverify_cast(FROM_T from)
Definition: UT_Assert.h:175
GA_BlobRef getOrderedBlob(exint idx) const
Lookup a blob given an ordered index.
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1221
exint entries() const
Alias of size(). size() is preferred.
Definition: UT_Array.h:446
double fpreal
Definition: SYS_Types.h:269
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.
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:338
virtual void compactStorage()
exint append(void)
Definition: UT_Array.h:95
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:107
virtual void destructElement(GA_Offset offset)
Callback invoked if needsDestruction() returns true.
Attribute Interface class to copy attribute data.
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:856
void clear()
Resets list to an empty list.
Definition: UT_Array.h:506
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.
GLenum src
Definition: glcorearb.h:1792