OpenVDB  8.1.1
PagedArray.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
14 
15 #ifndef OPENVDB_UTIL_PAGED_ARRAY_HAS_BEEN_INCLUDED
16 #define OPENVDB_UTIL_PAGED_ARRAY_HAS_BEEN_INCLUDED
17 
18 #include <openvdb/version.h>
19 #include <openvdb/Types.h>// SharedPtr
20 #include <deque>
21 #include <cassert>
22 #include <iostream>
23 #include <algorithm>// std::swap
24 #include <atomic>
25 #include <tbb/spin_mutex.h>
26 #include <tbb/parallel_for.h>
27 #include <tbb/parallel_sort.h>
28 
29 namespace openvdb {
31 namespace OPENVDB_VERSION_NAME {
32 namespace util {
33 
35 
36 
140 
141 template<typename ValueT, size_t Log2PageSize = 10UL>
143 {
144 private:
145  static_assert(Log2PageSize > 1UL, "Expected Log2PageSize > 1");
146  class Page;
147 
148  // must allow mutiple threads to call operator[] as long as only one thread calls push_back
149  using PageTableT = std::deque<Page*>;
150 
151 public:
152  using ValueType = ValueT;
154 
156  PagedArray() : mCapacity{0} { mSize = 0; }
157 
159  ~PagedArray() { this->clear(); }
160 
161  // Disallow copy construction and assignment
162  PagedArray(const PagedArray&) = delete;
163  PagedArray& operator=(const PagedArray&) = delete;
164 
166  static Ptr create() { return Ptr(new PagedArray); }
167 
176  class ValueBuffer;
177 
179  ValueBuffer getBuffer() { return ValueBuffer(*this); }
180 
182  class ConstIterator;
183 
185  class Iterator;
186 
189  {
190  return this->push_back_unsafe(value);
191  }
192 
198  size_t push_back_unsafe(const ValueType& value)
199  {
200  const size_t index = mSize.fetch_add(1);
201  if (index >= mCapacity) {
202  mPageTable.push_back( new Page() );
203  mCapacity += Page::Size;
204  }
205  (*mPageTable[index >> Log2PageSize])[index] = value;
206  return index;
207  }
208 
212  void shrink_to_fit();
213 
222  {
223  assert(i<mCapacity);
224  return (*mPageTable[i>>Log2PageSize])[i];
225  }
226 
234  const ValueType& operator[](size_t i) const
235  {
236  assert(i<mCapacity);
237  return (*mPageTable[i>>Log2PageSize])[i];
238  }
239 
245  void fill(const ValueType& v)
246  {
247  auto op = [&](const tbb::blocked_range<size_t>& r){
248  for(size_t i=r.begin(); i!=r.end(); ++i) mPageTable[i]->fill(v);
249  };
250  tbb::parallel_for(tbb::blocked_range<size_t>(0, this->pageCount()), op);
251  }
252 
260  bool copy(ValueType *p, size_t count) const
261  {
262  size_t last_page = count >> Log2PageSize;
263  if (last_page >= this->pageCount()) return false;
264  auto op = [&](const tbb::blocked_range<size_t>& r){
265  for (size_t i=r.begin(); i!=r.end(); ++i) {
266  mPageTable[i]->copy(p+i*Page::Size, Page::Size);
267  }
268  };
269  if (size_t m = count & Page::Mask) {//count is not divisible by page size
270  tbb::parallel_for(tbb::blocked_range<size_t>(0, last_page, 32), op);
271  mPageTable[last_page]->copy(p+last_page*Page::Size, m);
272  } else {
273  tbb::parallel_for(tbb::blocked_range<size_t>(0, last_page+1, 32), op);
274  }
275  return true;
276  }
277  void copy(ValueType *p) const { this->copy(p, mSize); }
278 
293  void resize(size_t size)
294  {
295  mSize = size;
296  if (size > mCapacity) {
297  this->grow(size-1);
298  } else {
299  this->shrink_to_fit();
300  }
301  }
302 
318  void resize(size_t size, const ValueType& v)
319  {
320  this->resize(size);
321  this->fill(v);
322  }
323 
325  size_t size() const { return mSize; }
326 
329  size_t capacity() const { return mCapacity; }
330 
333  size_t freeCount() const { return mCapacity - mSize; }
334 
336  size_t pageCount() const { return mPageTable.size(); }
337 
339  static size_t pageSize() { return Page::Size; }
340 
342  static size_t log2PageSize() { return Log2PageSize; }
343 
345  size_t memUsage() const
346  {
347  return sizeof(*this) + mPageTable.size() * Page::memUsage();
348  }
349 
351  bool isEmpty() const { return mSize == 0; }
352 
359  bool isPartiallyFull() const { return (mSize & Page::Mask) > 0; }
360 
364  void clear()
365  {
366  for (size_t i=0, n=mPageTable.size(); i<n; ++i) delete mPageTable[i];
367  PageTableT().swap(mPageTable);
368  mSize = 0;
369  mCapacity = 0;
370  }
371 
373  Iterator begin() { return Iterator(*this, 0); }
374 
380  Iterator end() { return Iterator(*this, mSize); }
381 
383  ConstIterator cbegin() const { return ConstIterator(*this, 0); }
385  ConstIterator begin() const { return ConstIterator(*this, 0); }
387 
389  ConstIterator cend() const { return ConstIterator(*this, mSize); }
395  ConstIterator end() const { return ConstIterator(*this, mSize); }
397 
399  void sort() { tbb::parallel_sort(this->begin(), this->end(), std::less<ValueT>() ); }
400 
402  void invSort() { tbb::parallel_sort(this->begin(), this->end(), std::greater<ValueT>()); }
403 
405  template <typename Functor>
410  void sort(Functor func) { tbb::parallel_sort(this->begin(), this->end(), func ); }
412 
420  void merge(PagedArray& other);
421 
423  void print(std::ostream& os = std::cout) const
424  {
425  os << "PagedArray:\n"
426  << "\tSize: " << this->size() << " elements\n"
427  << "\tPage table: " << this->pageCount() << " pages\n"
428  << "\tPage size: " << this->pageSize() << " elements\n"
429  << "\tCapacity: " << this->capacity() << " elements\n"
430  << "\tFootprint: " << this->memUsage() << " bytes\n";
431  }
432 
433 private:
434 
435  friend class ValueBuffer;
436 
437  void grow(size_t index)
438  {
439  tbb::spin_mutex::scoped_lock lock(mGrowthMutex);
440  while(index >= mCapacity) {
441  mPageTable.push_back( new Page() );
442  mCapacity += Page::Size;
443  }
444  }
445 
446  void add_full(Page*& page, size_t size);
447 
448  void add_partially_full(Page*& page, size_t size);
449 
450  void add(Page*& page, size_t size) {
451  tbb::spin_mutex::scoped_lock lock(mGrowthMutex);
452  if (size == Page::Size) {//page is full
453  this->add_full(page, size);
454  } else if (size>0) {//page is only partially full
455  this->add_partially_full(page, size);
456  }
457  }
458  PageTableT mPageTable;//holds points to allocated pages
459  std::atomic<size_t> mSize;// current number of elements in array
460  size_t mCapacity;//capacity of array given the current page count
461  tbb::spin_mutex mGrowthMutex;//Mutex-lock required to grow pages
462 }; // Public class PagedArray
463 
465 
466 template <typename ValueT, size_t Log2PageSize>
468 {
469  if (mPageTable.size() > (mSize >> Log2PageSize) + 1) {
470  tbb::spin_mutex::scoped_lock lock(mGrowthMutex);
471  const size_t pageCount = (mSize >> Log2PageSize) + 1;
472  if (mPageTable.size() > pageCount) {
473  delete mPageTable.back();
474  mPageTable.pop_back();
475  mCapacity -= Page::Size;
476  }
477  }
478 }
479 
480 template <typename ValueT, size_t Log2PageSize>
482 {
483  if (&other != this && !other.isEmpty()) {
484  tbb::spin_mutex::scoped_lock lock(mGrowthMutex);
485  // extract last partially full page if it exists
486  Page* page = nullptr;
487  const size_t size = mSize & Page::Mask; //number of elements in the last page
488  if ( size > 0 ) {
489  page = mPageTable.back();
490  mPageTable.pop_back();
491  mSize -= size;
492  }
493  // transfer all pages from the other page table
494  mPageTable.insert(mPageTable.end(), other.mPageTable.begin(), other.mPageTable.end());
495  mSize += other.mSize;
496  mCapacity = Page::Size*mPageTable.size();
497  other.mSize = 0;
498  other.mCapacity = 0;
499  PageTableT().swap(other.mPageTable);
500  // add back last partially full page
501  if (page) this->add_partially_full(page, size);
502  }
503 }
504 
505 template <typename ValueT, size_t Log2PageSize>
506 void PagedArray<ValueT, Log2PageSize>::add_full(Page*& page, size_t size)
507 {
508  assert(size == Page::Size);//page must be full
509  if (mSize & Page::Mask) {//page-table is partially full
510  Page*& tmp = mPageTable.back();
511  std::swap(tmp, page);//swap last table entry with page
512  }
513  mPageTable.push_back(page);
514  mCapacity += Page::Size;
515  mSize += size;
516  page = nullptr;
517 }
518 
519 template <typename ValueT, size_t Log2PageSize>
521 {
522  assert(size > 0 && size < Page::Size);//page must be partially full
523  if (size_t m = mSize & Page::Mask) {//page table is also partially full
524  ValueT *s = page->data(), *t = mPageTable.back()->data() + m;
525  for (size_t i=std::min(mSize+size, mCapacity)-mSize; i; --i) *t++ = *s++;
526  if (mSize+size > mCapacity) {//grow page table
527  mPageTable.push_back( new Page() );
528  t = mPageTable.back()->data();
529  for (size_t i=mSize+size-mCapacity; i; --i) *t++ = *s++;
530  mCapacity += Page::Size;
531  }
532  } else {//page table is full so simply append page
533  mPageTable.push_back( page );
534  mCapacity += Page::Size;
535  page = nullptr;
536  }
537  mSize += size;
538 }
539 
541 
542 // Public member-class of PagedArray
543 template <typename ValueT, size_t Log2PageSize>
544 class PagedArray<ValueT, Log2PageSize>::
546 {
547 public:
550  ValueBuffer(PagedArray& parent) : mParent(&parent), mPage(new Page()), mSize(0) {}
553  ValueBuffer(const ValueBuffer& other) : mParent(other.mParent), mPage(new Page()), mSize(0) {}
555  ~ValueBuffer() { mParent->add(mPage, mSize); delete mPage; }
556 
557  ValueBuffer& operator=(const ValueBuffer&) = delete;// disallow copy assignment
558 
563  void push_back(const ValueT& v) {
564  (*mPage)[mSize++] = v;
565  if (mSize == Page::Size) this->flush();
566  }
572  void flush() {
573  mParent->add(mPage, mSize);
574  if (mPage == nullptr) mPage = new Page();
575  mSize = 0;
576  }
578  PagedArrayType& parent() const { return *mParent; }
580  size_t size() const { return mSize; }
581  static size_t pageSize() { return 1UL << Log2PageSize; }
582 private:
583  PagedArray* mParent;
584  Page* mPage;
585  size_t mSize;
586 };// Public class PagedArray::ValueBuffer
587 
589 
590 // Const std-compliant iterator
591 // Public member-class of PagedArray
592 template <typename ValueT, size_t Log2PageSize>
593 class PagedArray<ValueT, Log2PageSize>::
594 ConstIterator : public std::iterator<std::random_access_iterator_tag, ValueT>
595 {
596 public:
597  using BaseT = std::iterator<std::random_access_iterator_tag, ValueT>;
598  using difference_type = typename BaseT::difference_type;
599  // constructors and assignment
600  ConstIterator() : mPos(0), mParent(nullptr) {}
601  ConstIterator(const PagedArray& parent, size_t pos=0) : mPos(pos), mParent(&parent) {}
602  ConstIterator(const ConstIterator& other) : mPos(other.mPos), mParent(other.mParent) {}
604  mPos=other.mPos;
605  mParent=other.mParent;
606  return *this;
607  }
608  // prefix
609  ConstIterator& operator++() { ++mPos; return *this; }
610  ConstIterator& operator--() { --mPos; return *this; }
611  // postfix
612  ConstIterator operator++(int) { ConstIterator tmp(*this); ++mPos; return tmp; }
613  ConstIterator operator--(int) { ConstIterator tmp(*this); --mPos; return tmp; }
614  // value access
615  const ValueT& operator*() const { return (*mParent)[mPos]; }
616  const ValueT* operator->() const { return &(this->operator*()); }
617  const ValueT& operator[](const difference_type& pos) const { return (*mParent)[mPos+pos]; }
618  // offset
619  ConstIterator& operator+=(const difference_type& pos) { mPos += pos; return *this; }
620  ConstIterator& operator-=(const difference_type& pos) { mPos -= pos; return *this; }
621  ConstIterator operator+(const difference_type &pos) const { return Iterator(*mParent,mPos+pos); }
622  ConstIterator operator-(const difference_type &pos) const { return Iterator(*mParent,mPos-pos); }
623  difference_type operator-(const ConstIterator& other) const { return mPos - other.pos(); }
624  // comparisons
625  bool operator==(const ConstIterator& other) const { return mPos == other.mPos; }
626  bool operator!=(const ConstIterator& other) const { return mPos != other.mPos; }
627  bool operator>=(const ConstIterator& other) const { return mPos >= other.mPos; }
628  bool operator<=(const ConstIterator& other) const { return mPos <= other.mPos; }
629  bool operator< (const ConstIterator& other) const { return mPos < other.mPos; }
630  bool operator> (const ConstIterator& other) const { return mPos > other.mPos; }
631  // non-std methods
632  bool isValid() const { return mParent != nullptr && mPos < mParent->size(); }
633  size_t pos() const { return mPos; }
634 private:
635  size_t mPos;
636  const PagedArray* mParent;
637 };// Public class PagedArray::ConstIterator
638 
640 
641 // Non-const std-compliant iterator
642 // Public member-class of PagedArray
643 template <typename ValueT, size_t Log2PageSize>
644 class PagedArray<ValueT, Log2PageSize>::
645 Iterator : public std::iterator<std::random_access_iterator_tag, ValueT>
646 {
647 public:
648  using BaseT = std::iterator<std::random_access_iterator_tag, ValueT>;
649  using difference_type = typename BaseT::difference_type;
650  // constructors and assignment
651  Iterator() : mPos(0), mParent(nullptr) {}
652  Iterator(PagedArray& parent, size_t pos=0) : mPos(pos), mParent(&parent) {}
653  Iterator(const Iterator& other) : mPos(other.mPos), mParent(other.mParent) {}
654  Iterator& operator=(const Iterator& other) {
655  mPos=other.mPos;
656  mParent=other.mParent;
657  return *this;
658  }
659  // prefix
660  Iterator& operator++() { ++mPos; return *this; }
661  Iterator& operator--() { --mPos; return *this; }
662  // postfix
663  Iterator operator++(int) { Iterator tmp(*this); ++mPos; return tmp; }
664  Iterator operator--(int) { Iterator tmp(*this); --mPos; return tmp; }
665  // value access
666  ValueT& operator*() const { return (*mParent)[mPos]; }
667  ValueT* operator->() const { return &(this->operator*()); }
668  ValueT& operator[](const difference_type& pos) const { return (*mParent)[mPos+pos]; }
669  // offset
670  Iterator& operator+=(const difference_type& pos) { mPos += pos; return *this; }
671  Iterator& operator-=(const difference_type& pos) { mPos -= pos; return *this; }
672  Iterator operator+(const difference_type &pos) const { return Iterator(*mParent, mPos+pos); }
673  Iterator operator-(const difference_type &pos) const { return Iterator(*mParent, mPos-pos); }
674  difference_type operator-(const Iterator& other) const { return mPos - other.pos(); }
675  // comparisons
676  bool operator==(const Iterator& other) const { return mPos == other.mPos; }
677  bool operator!=(const Iterator& other) const { return mPos != other.mPos; }
678  bool operator>=(const Iterator& other) const { return mPos >= other.mPos; }
679  bool operator<=(const Iterator& other) const { return mPos <= other.mPos; }
680  bool operator< (const Iterator& other) const { return mPos < other.mPos; }
681  bool operator> (const Iterator& other) const { return mPos > other.mPos; }
682  // non-std methods
683  bool isValid() const { return mParent != nullptr && mPos < mParent->size(); }
684  size_t pos() const { return mPos; }
685  private:
686  size_t mPos;
687  PagedArray* mParent;
688 };// Public class PagedArray::Iterator
689 
691 
692 // Private member-class of PagedArray implementing a memory page
693 template <typename ValueT, size_t Log2PageSize>
694 class PagedArray<ValueT, Log2PageSize>::
695 Page
696 {
697 public:
698  static const size_t Size = 1UL << Log2PageSize;
699  static const size_t Mask = Size - 1UL;
700  static size_t memUsage() { return sizeof(ValueT)*Size; }
701  // Raw memory allocation without any initialization
702  Page() : mData(reinterpret_cast<ValueT*>(new char[sizeof(ValueT)*Size])) {}
703  ~Page() { delete [] mData; }
704  Page(const Page&) = delete;//copy construction is not implemented
705  Page& operator=(const Page&) = delete;//copy assignment is not implemented
706  ValueT& operator[](const size_t i) { return mData[i & Mask]; }
707  const ValueT& operator[](const size_t i) const { return mData[i & Mask]; }
708  void fill(const ValueT& v) {
709  ValueT* dst = mData;
710  for (size_t i=Size; i; --i) *dst++ = v;
711  }
712  ValueT* data() { return mData; }
713  // Copy the first n elements of this Page to dst (which is assumed to large
714  // enough to hold the n elements).
715  void copy(ValueType *dst, size_t n) const {
716  const ValueT* src = mData;
717  for (size_t i=n; i; --i) *dst++ = *src++;
718  }
719 protected:
720  ValueT* mData;
721 };// Private class PagedArray::Page
722 
724 
725 } // namespace util
726 } // namespace OPENVDB_VERSION_NAME
727 } // namespace openvdb
728 
729 #endif // OPENVDB_UTIL_PAGED_ARRAY_HAS_BEEN_INCLUDED
typename BaseT::difference_type difference_type
Definition: PagedArray.h:598
Iterator()
Definition: PagedArray.h:651
static size_t pageSize()
Return the number of elements per memory page.
Definition: PagedArray.h:339
ValueT ValueType
Definition: PagedArray.h:152
void fill(const ValueType &v)
Set all elements in the page table to the specified value.
Definition: PagedArray.h:245
size_t memUsage() const
Return the memory footprint of this array in bytes.
Definition: PagedArray.h:345
Iterator operator--(int)
Definition: PagedArray.h:664
#define OPENVDB_DEPRECATED
Definition: Platform.h:122
void fill(const ValueT &v)
Definition: PagedArray.h:708
ConstIterator & operator=(const ConstIterator &other)
Definition: PagedArray.h:603
Iterator & operator-=(const difference_type &pos)
Definition: PagedArray.h:671
ConstIterator & operator--()
Definition: PagedArray.h:610
size_t freeCount() const
Return the number of additional elements that can be added to this array without allocating more memo...
Definition: PagedArray.h:333
size_t push_back_unsafe(const ValueType &value)
Definition: PagedArray.h:198
~ValueBuffer()
Destructor that transfers an buffered values to the parent PagedArray.
Definition: PagedArray.h:555
ValueT * operator->() const
Definition: PagedArray.h:667
~PagedArray()
Destructor removed all allocated pages.
Definition: PagedArray.h:159
bool isPartiallyFull() const
Return true if the page table is partially full, i.e. the last non-empty page contains less than page...
Definition: PagedArray.h:359
void invSort()
Parallel sort of all the elements in descending order.
Definition: PagedArray.h:402
ConstIterator operator+(const difference_type &pos) const
Definition: PagedArray.h:621
bool isEmpty() const
Return true if the container contains no elements.
Definition: PagedArray.h:351
size_t capacity() const
Return the maximum number of elements that this array can contain without allocating more memory page...
Definition: PagedArray.h:329
bool operator<=(const ConstIterator &other) const
Definition: PagedArray.h:628
bool operator<=(const Iterator &other) const
Definition: PagedArray.h:679
static size_t pageSize()
Definition: PagedArray.h:581
bool isValid() const
Definition: PagedArray.h:632
difference_type operator-(const Iterator &other) const
Definition: PagedArray.h:674
ValueT & operator*() const
Definition: PagedArray.h:666
ValueBuffer(const ValueBuffer &other)
Definition: PagedArray.h:553
bool copy(ValueType *p, size_t count) const
Copy the first count values in this PageArray into a raw c-style array, assuming it to be at least co...
Definition: PagedArray.h:260
const ValueT & operator[](const difference_type &pos) const
Definition: PagedArray.h:617
ConstIterator & operator++()
Definition: PagedArray.h:609
Iterator operator-(const difference_type &pos) const
Definition: PagedArray.h:673
void print(std::ostream &os=std::cout) const
Print information for debugging.
Definition: PagedArray.h:423
std::shared_ptr< T > SharedPtr
Definition: openvdb/Types.h:110
size_t pageCount() const
Return the number of allocated memory pages.
Definition: PagedArray.h:336
void resize(size_t size, const ValueType &v)
Resize this array to the specified size and initialize all values to v.
Definition: PagedArray.h:318
Iterator begin()
Return a non-const iterator pointing to the first element.
Definition: PagedArray.h:373
bool operator!=(const ConstIterator &other) const
Definition: PagedArray.h:626
std::iterator< std::random_access_iterator_tag, ValueT > BaseT
Definition: PagedArray.h:597
Iterator(PagedArray &parent, size_t pos=0)
Definition: PagedArray.h:652
static size_t log2PageSize()
Return log2 of the number of elements per memory page.
Definition: PagedArray.h:342
PagedArray()
Default constructor.
Definition: PagedArray.h:156
bool operator<(const Tuple< SIZE, T0 > &t0, const Tuple< SIZE, T1 > &t1)
Definition: Tuple.h:189
Definition: PagedArray.h:694
PagedArrayType & parent() const
Return a reference to the parent PagedArray.
Definition: PagedArray.h:578
OPENVDB_DEPRECATED size_t push_back(const ValueType &value)
This method is deprecated and will be removed shortly!
Definition: PagedArray.h:188
ConstIterator & operator-=(const difference_type &pos)
Definition: PagedArray.h:620
Iterator operator+(const difference_type &pos) const
Definition: PagedArray.h:672
bool operator>=(const Iterator &other) const
Definition: PagedArray.h:678
const ValueT & operator*() const
Definition: PagedArray.h:615
Definition: openvdb/Exceptions.h:13
static Ptr create()
Return a shared pointer to a new instance of this class.
Definition: PagedArray.h:166
ValueT & operator[](const difference_type &pos) const
Definition: PagedArray.h:668
bool isValid() const
Definition: PagedArray.h:683
ConstIterator operator--(int)
Definition: PagedArray.h:613
Iterator(const Iterator &other)
Definition: PagedArray.h:653
Iterator & operator++()
Definition: PagedArray.h:660
ConstIterator(const PagedArray &parent, size_t pos=0)
Definition: PagedArray.h:601
ConstIterator begin() const
Return a const iterator pointing to the first element.
Definition: PagedArray.h:385
ValueBuffer(PagedArray &parent)
Constructor from a PageArray.
Definition: PagedArray.h:550
bool operator==(const ConstIterator &other) const
Definition: PagedArray.h:625
Iterator & operator=(const Iterator &other)
Definition: PagedArray.h:654
ConstIterator(const ConstIterator &other)
Definition: PagedArray.h:602
ConstIterator()
Definition: PagedArray.h:600
void resize(size_t size)
Resize this array to the specified size.
Definition: PagedArray.h:293
void push_back(const ValueT &v)
Add a value to the buffer and increment the size.
Definition: PagedArray.h:563
size_t pos() const
Definition: PagedArray.h:684
size_t size() const
Return the number of elements in this array.
Definition: PagedArray.h:325
ValueType & operator[](size_t i)
Return a reference to the value at the specified offset.
Definition: PagedArray.h:221
difference_type operator-(const ConstIterator &other) const
Definition: PagedArray.h:623
Iterator operator++(int)
Definition: PagedArray.h:663
void clear()
Removes all elements from the array and delete all pages.
Definition: PagedArray.h:364
bool operator>=(const ConstIterator &other) const
Definition: PagedArray.h:627
void copy(ValueType *p) const
Definition: PagedArray.h:277
size_t size() const
Return the current number of elements cached in this buffer.
Definition: PagedArray.h:580
Definition: PagedArray.h:644
~Page()
Definition: PagedArray.h:703
ValueT * data()
Definition: PagedArray.h:712
const ValueT & operator[](const size_t i) const
Definition: PagedArray.h:707
const ValueT * operator->() const
Definition: PagedArray.h:616
bool operator==(const Iterator &other) const
Definition: PagedArray.h:676
void sort(Functor func)
Parallel sort of all the elements based on a custom functor with the api:
Definition: PagedArray.h:410
Iterator & operator+=(const difference_type &pos)
Definition: PagedArray.h:670
Mat3< typename promote< T0, T1 >::type > operator*(const Mat3< T0 > &m0, const Mat3< T1 > &m1)
Multiply m0 by m1 and return the resulting matrix.
Definition: Mat3.h:611
Iterator & operator--()
Definition: PagedArray.h:661
bool operator!=(const Iterator &other) const
Definition: PagedArray.h:677
Index64 memUsage(const TreeT &tree, bool threaded=true)
Return the total amount of memory in bytes occupied by this tree.
Definition: Count.h:233
void flush()
Manually transfers the values in this buffer to the parent PagedArray.
Definition: PagedArray.h:572
ValueT * mData
Definition: PagedArray.h:720
static size_t memUsage()
Definition: PagedArray.h:700
const std::enable_if<!VecTraits< T >::IsVec, T >::type & min(const T &a, const T &b)
Definition: Composite.h:103
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:116
ConstIterator operator++(int)
Definition: PagedArray.h:612
Iterator end()
Return a non-const iterator pointing to the past-the-last element.
Definition: PagedArray.h:380
const ValueType & operator[](size_t i) const
Return a const-reference to the value at the specified offset.
Definition: PagedArray.h:234
std::iterator< std::random_access_iterator_tag, ValueT > BaseT
Definition: PagedArray.h:648
void copy(ValueType *dst, size_t n) const
Definition: PagedArray.h:715
SharedPtr< PagedArray > Ptr
Definition: PagedArray.h:153
ValueT & operator[](const size_t i)
Definition: PagedArray.h:706
ConstIterator operator-(const difference_type &pos) const
Definition: PagedArray.h:622
ValueBuffer getBuffer()
Definition: PagedArray.h:179
ConstIterator & operator+=(const difference_type &pos)
Definition: PagedArray.h:619
ConstIterator end() const
Return a const iterator pointing to the past-the-last element.
Definition: PagedArray.h:395
typename BaseT::difference_type difference_type
Definition: PagedArray.h:649
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:178
Concurrent, page-based, dynamically-sized linear data structure with O(1) random access and STL-compl...
Definition: PagedArray.h:142
size_t pos() const
Definition: PagedArray.h:633
bool operator>(const Tuple< SIZE, T0 > &t0, const Tuple< SIZE, T1 > &t1)
Definition: Tuple.h:201
void sort()
Parallel sort of all the elements in ascending order.
Definition: PagedArray.h:399
Page()
Definition: PagedArray.h:702