From 610842af9eec6b49258311b96485447476305faa Mon Sep 17 00:00:00 2001 From: Brian Salomon Date: Fri, 16 Jun 2017 06:47:30 -0400 Subject: Make SkTArray maintain reserve count Bug: skia:6690 Change-Id: I01f5bb56c654f513365d6ce9f19712d9be07a08d Reviewed-on: https://skia-review.googlesource.com/20055 Commit-Queue: Brian Salomon Reviewed-by: Yuqian Li --- include/private/SkTArray.h | 54 ++++++++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 19 deletions(-) (limited to 'include/private') diff --git a/include/private/SkTArray.h b/include/private/SkTArray.h index 4b700d2d29..a6e4dedf9f 100644 --- a/include/private/SkTArray.h +++ b/include/private/SkTArray.h @@ -96,12 +96,15 @@ public: } /** - * Resets to count() == 0 + * Resets to count() == 0 and resets any reserve count. */ - void reset() { this->pop_back_n(fCount); } + void reset() { + this->pop_back_n(fCount); + fReserved = false; + } /** - * Resets to count() = n newly constructed T objects. + * Resets to count() = n newly constructed T objects and resets any reserve count. */ void reset(int n) { SkASSERT(n >= 0); @@ -115,19 +118,11 @@ public: for (int i = 0; i < fCount; ++i) { new (fItemArray + i) T; } + fReserved = false; } /** - * Ensures there is enough reserved space for n elements. - */ - void reserve(int n) { - if (fCount < n) { - this->checkRealloc(n - fCount); - } - } - - /** - * Resets to a copy of a C array. + * Resets to a copy of a C array and resets any reserve count. */ void reset(const T* array, int count) { for (int i = 0; i < fCount; ++i) { @@ -137,6 +132,22 @@ public: this->checkRealloc(count); fCount = count; this->copy(array); + fReserved = false; + } + + /** + * Ensures there is enough reserved space for n additional elements. The is guaranteed at least + * until the array size grows above n and subsequently shrinks below n, any version of reset() + * is called, or reserve() is called again. + */ + void reserve(int n) { + SkASSERT(n >= 0); + if (n > 0) { + this->checkRealloc(n); + fReserved = fOwnMemory; + } else { + fReserved = false; + } } void removeShuffle(int n) { @@ -431,10 +442,12 @@ private: fAllocCount = 0; fMemArray = nullptr; fOwnMemory = false; + fReserved = false; } else { fAllocCount = SkTMax(count, SkTMax(kMinHeapAllocCount, reserveCount)); fMemArray = sk_malloc_throw(fAllocCount * sizeof(T)); fOwnMemory = true; + fReserved = reserveCount > 0; } } @@ -444,6 +457,7 @@ private: SkASSERT(preallocStorage); fCount = count; fMemArray = nullptr; + fReserved = false; if (count > preallocCount) { fAllocCount = SkTMax(count, kMinHeapAllocCount); fMemArray = sk_malloc_throw(fAllocCount * sizeof(T)); @@ -505,10 +519,10 @@ private: int newCount = fCount + delta; // We allow fAllocCount to be in the range [newCount, 3*newCount]. We also never shrink - // when we're currently using preallocated memory or would allocate less than - // kMinHeapAllocCount. + // when we're currently using preallocated memory, would allocate less than + // kMinHeapAllocCount, or a reserve count was specified that has yet to be exceeded. bool mustGrow = newCount > fAllocCount; - bool shouldShrink = fAllocCount > 3 * newCount && fOwnMemory; + bool shouldShrink = fAllocCount > 3 * newCount && fOwnMemory && !fReserved; if (!mustGrow && !shouldShrink) { return; } @@ -531,15 +545,17 @@ private: } fMemArray = newMemArray; fOwnMemory = true; + fReserved = false; } - int fCount; - int fAllocCount; - bool fOwnMemory; union { T* fItemArray; void* fMemArray; }; + int fCount; + int fAllocCount; + bool fOwnMemory : 1; + bool fReserved : 1; }; template constexpr int SkTArray::kMinHeapAllocCount; -- cgit v1.2.3