SkDeque.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /*
  2. * Copyright 2006 The Android Open Source Project
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #ifndef SkDeque_DEFINED
  8. #define SkDeque_DEFINED
  9. #include "../private/SkNoncopyable.h"
  10. #include "SkTypes.h"
  11. /*
  12. * The deque class works by blindly creating memory space of a specified element
  13. * size. It manages the memory as a doubly linked list of blocks each of which
  14. * can contain multiple elements. Pushes and pops add/remove blocks from the
  15. * beginning/end of the list as necessary while each block tracks the used
  16. * portion of its memory.
  17. * One behavior to be aware of is that the pops do not immediately remove an
  18. * empty block from the beginning/end of the list (Presumably so push/pop pairs
  19. * on the block boundaries don't cause thrashing). This can result in the first/
  20. * last element not residing in the first/last block.
  21. */
  22. class SK_API SkDeque : SkNoncopyable {
  23. public:
  24. /**
  25. * elemSize specifies the size of each individual element in the deque
  26. * allocCount specifies how many elements are to be allocated as a block
  27. */
  28. explicit SkDeque(size_t elemSize, int allocCount = 1);
  29. SkDeque(size_t elemSize, void* storage, size_t storageSize, int allocCount = 1);
  30. ~SkDeque();
  31. bool empty() const { return 0 == fCount; }
  32. int count() const { return fCount; }
  33. size_t elemSize() const { return fElemSize; }
  34. const void* front() const { return fFront; }
  35. const void* back() const { return fBack; }
  36. void* front() {
  37. return (void*)((const SkDeque*)this)->front();
  38. }
  39. void* back() {
  40. return (void*)((const SkDeque*)this)->back();
  41. }
  42. /**
  43. * push_front and push_back return a pointer to the memory space
  44. * for the new element
  45. */
  46. void* push_front();
  47. void* push_back();
  48. void pop_front();
  49. void pop_back();
  50. private:
  51. struct Block;
  52. public:
  53. class Iter {
  54. public:
  55. enum IterStart {
  56. kFront_IterStart,
  57. kBack_IterStart,
  58. };
  59. /**
  60. * Creates an uninitialized iterator. Must be reset()
  61. */
  62. Iter();
  63. Iter(const SkDeque& d, IterStart startLoc);
  64. void* next();
  65. void* prev();
  66. void reset(const SkDeque& d, IterStart startLoc);
  67. private:
  68. SkDeque::Block* fCurBlock;
  69. char* fPos;
  70. size_t fElemSize;
  71. };
  72. // Inherit privately from Iter to prevent access to reverse iteration
  73. class F2BIter : private Iter {
  74. public:
  75. F2BIter() {}
  76. /**
  77. * Wrap Iter's 2 parameter ctor to force initialization to the
  78. * beginning of the deque
  79. */
  80. F2BIter(const SkDeque& d) : INHERITED(d, kFront_IterStart) {}
  81. using Iter::next;
  82. /**
  83. * Wrap Iter::reset to force initialization to the beginning of the
  84. * deque
  85. */
  86. void reset(const SkDeque& d) {
  87. this->INHERITED::reset(d, kFront_IterStart);
  88. }
  89. private:
  90. typedef Iter INHERITED;
  91. };
  92. private:
  93. // allow unit test to call numBlocksAllocated
  94. friend class DequeUnitTestHelper;
  95. void* fFront;
  96. void* fBack;
  97. Block* fFrontBlock;
  98. Block* fBackBlock;
  99. size_t fElemSize;
  100. void* fInitialStorage;
  101. int fCount; // number of elements in the deque
  102. int fAllocCount; // number of elements to allocate per block
  103. Block* allocateBlock(int allocCount);
  104. void freeBlock(Block* block);
  105. /**
  106. * This returns the number of chunk blocks allocated by the deque. It
  107. * can be used to gauge the effectiveness of the selected allocCount.
  108. */
  109. int numBlocksAllocated() const;
  110. };
  111. #endif