HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GA_RangeTypeInterface.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_RangeTypeInterface.h ( GA Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __GA_RangeTypeInterface__
12 #define __GA_RangeTypeInterface__
13 
14 #include "GA_API.h"
15 #include "GA_Types.h"
16 
17 #include <SYS/SYS_AtomicInt.h>
18 
19 #include <stddef.h>
20 
21 
22 class GA_IndexMap;
23 class GA_IteratorState;
24 class GA_Range;
26 
27 
28 #define GA_SPLIT_GRANULARITY GA_PAGE_SIZE
29 
30 /// @brief Abstract implementation of a range
31 ///
32 /// A range specifies a selection/collection of elements in an index map.
33 /// The range also provides an iterator over its elements.
34 ///
35 /// With operation on ranges, the user may want to parallelize operations on
36 /// the range. This is done by splitting the range into multiple new range.
37 /// Not all ranges can be split.
38 ///
39 /// @see GA_Range
41 {
42 public:
45  virtual ~GA_RangeTypeInterface();
46 
47  /// Query type of element
48  GA_AttributeOwner getOwner() const;
49 
50  /// Convenience method to test whether the range is divisible
51  bool is_divisible() const
52  {
53  return isSplittable() && getPageCount() > 1;
54  }
55 
56  /// Method to create a copy of this selection
57  virtual GA_RangeTypeInterface *copy() const = 0;
58 
59  /// Split into two existing ranges
60  bool splitIntoRanges(GA_Range &r1, GA_Range &r2) const;
61 
62  /// Split the range into 2 separate ranges.
63  /// @note the split ranges @b must contain separate pages of offsets. That
64  /// is a single page cannot be split.
65  virtual bool split(GA_RangeTypeInterface *list[2]) const = 0;
66 
67  /// Return whether the RTI is capable of splitting. If this method returns
68  /// true, the range should be able to:
69  /// - Perform a binary split into two ranges if there are more than one
70  /// page of data in the range.
71  /// - Create an iterator which will iterate over the elements in a given
72  /// range of pages.
73  ///
74  /// For a range to be splittable, you need to implement the following four
75  /// methods:
76  /// - split()
77  /// - getPageCount()
78  /// - getPageElementRange()
79  /// - getFirstOffsetInPage()
80  /// @ref HDK_GA_Using_Parallel
81  virtual bool isSplittable() const = 0;
82 
83  /// For splittable ranges, return the number of pages contained in the range
84  virtual GA_Size getPageCount() const = 0;
85 
86  /// If a page is splittable, this method returns an iterator for the
87  /// elements in a set of @c npages pages.
88  /// The @c relative_page passed in will be between 0 and @c getPageCount()
89  /// and should be considered a relative page in the range.
90  /// For non-splittable ranges, you can implement the method using @code
91  /// virtual bool getPageElementRange(GA_Range &, GA_Size, GA_Size) const
92  /// { return getPageElementRangeNonSplittable(); }
93  /// @endcode
94  virtual bool getPageElementRange(GA_Range &range,
95  GA_Size relative_page,
96  GA_Size npages=1) const = 0;
97 
98  /// If a page is splittable, this method must return the first offset in
99  /// the given page.
100  /// The @c relative_page passed in will be between 0 and @c getPageCount()
101  /// and should be considered a relative page in the range.
102  /// For non-splittable ranges, you can implement the method using @code
103  /// virtual GA_Range getFirstOffsetInPage(GA_Size, GA_Size) const
104  /// { return getFirstOffsetInPageNonSplittable(); }
105  /// @endcode
106  virtual GA_Offset getFirstOffsetInPage(GA_Size relative_page) const = 0;
107 
108  /// Check whether the range is empty
109  virtual bool isEmpty() const = 0;
110 
111  /// @{
112  /// Compare two ranges
113  virtual bool isEqual(const GA_RangeTypeInterface &src) const = 0;
115  {
116  return ((&getIndexMap() == &src.getIndexMap())
117  && isEqual(src));
118  }
119  /// @}
120 
121  /// Get an upper bound on the size of the range
122  virtual GA_Size getMaxEntries() const = 0;
123 
124  /// Get an exact count of the size of the range
125  /// @see computeEntries()
126  virtual GA_Size getEntries() const = 0;
127 
128  /// @{
129  /// Construct/destruct the iterator state.
130  virtual void iterateCreate(GA_IteratorState &state) const { }
131  virtual void iterateDestroy(GA_IteratorState &state) const { }
132  /// @}
133 
134  /// Copy iterator state. The dest state will @b not have been constructed.
135  virtual void iterateCopy(GA_IteratorState &dest,
136  const GA_IteratorState &src) const = 0;
137 
138  /// Rewind the iterator (i.e. reset the iterator state). The start/offset
139  /// should be initialized so that they define the first contiguous "block"
140  /// for iteration. If the range is empty, @c start should be greater than
141  /// @c end. No "block" is allowed to cross a page boundary.
142  ///
143  /// The semantics are that @c start is in the range and @end is one larger
144  /// than the last element in the range. For example, @code
145  /// start := 6
146  /// end := 9
147  /// elements := [6, 7, 8]
148  /// @endcode
149  virtual void iterateRewind(GA_IteratorState &state,
150  GA_Offset &start, GA_Offset &end) const = 0;
151 
152  /// Choose the next contiguous range. If the iteration is complete,
153  /// @c start should be set to a value greater than @c end. No "block"
154  /// is allowed to cross a page boundary.
155  virtual void iterateNext(GA_IteratorState &state,
156  GA_Offset &start, GA_Offset &end) const = 0;
157 
158  /// Query if the RTI is ordered according to the index.
159  virtual bool isOrdered() const;
160 
161  /// Query if it is safe to delete an element during traversal. The method
162  /// defaults to false.
163  virtual bool areTraversalDeletionsSafe() const;
164 
165  /// Query if the RTI contains duplicates. If it cannot, then optimizations
166  /// can be made assuming that there are no duplicates in the range. This
167  /// defaults to true.
168  virtual bool canContainDuplicates() const { return true; }
169 
170  /// Allocate an object to allow us to query whether individual elements
171  /// are traversed by this range implementation. The responsibility for
172  /// deleting the resulting object lies with the caller.
173  ///
174  /// The default implementation will work for all derived classes, but
175  /// more efficient implementations are often possible.
176  virtual const GA_RangeMemberQuery *allocMemberQuery() const;
177 
178  /// Accessor for the index map
179  const GA_IndexMap &getIndexMap() const { return *myIndexMap; }
180 
181  /// @{
182  /// Reference tracking for RTI's, necessary for GA_Range.
183  void incref() const;
184  void decref() const;
185  /// @}
186 
187 public:
188  /// @{
189  /// Memory tracking for RTI's
190  // In place constructor
191  static void *operator new(size_t size, void *p) { return p; }
192  static void *operator new(size_t size);
193  static void operator delete(void *p, size_t size);
194  /// @}
195 
196 protected:
197  /// Method which can be called for getPageElementRange()
198  bool getPageElementRangeNonSplittable() const;
199 
200  /// Method which can be called for getFirstOffsetInPage()
201  GA_Offset getFirstOffsetInPageNonSplittable() const;
202 
203  /// This method creates an iterator and counts the entries.
204  GA_Size computeEntries() const;
205 
206 private:
207  const GA_IndexMap *myIndexMap;
208 
209  mutable SYS_AtomicInt32 myRefCount;
210 
211  // GA_RTIFiltered is a friend to be able to access the single iteration
212  // methods for its contained filter.
213  //friend class GA_RTIFiltered;
214 };
215 #endif
A class to manage an ordered array which has fixed offset handles.
Definition: GA_IndexMap.h:63
bool is_divisible() const
Convenience method to test whether the range is divisible.
GLenum GLint * range
Definition: glcorearb.h:1925
OIIO_UTIL_API bool copy(string_view from, string_view to, std::string &err)
GLuint start
Definition: glcorearb.h:475
virtual void iterateDestroy(GA_IteratorState &state) const
virtual bool canContainDuplicates() const
#define GA_API
Definition: GA_API.h:14
Abstract base class for a range membership query object.
bool operator==(const GA_RangeTypeInterface &src) const
exint GA_Size
Defines the bit width for index and offset types in GA.
Definition: GA_Types.h:235
A range of elements in an index-map.
Definition: GA_Range.h:42
virtual void iterateCreate(GA_IteratorState &state) const
GA_Size GA_Offset
Definition: GA_Types.h:641
GLuint GLuint end
Definition: glcorearb.h:475
Abstract implementation of a range.
GLsizeiptr size
Definition: glcorearb.h:664
GA_AttributeOwner
Definition: GA_Types.h:34
const GA_IndexMap & getIndexMap() const
Accessor for the index map.
void OIIO_UTIL_API split(string_view str, std::vector< string_view > &result, string_view sep=string_view(), int maxsplit=-1)
GLenum src
Definition: glcorearb.h:1793