Bumping manifests a=b2g-bump
[gecko.git] / xpcom / io / nsSegmentedBuffer.h
blob37b3a8e4fc59e94ce23cb3549403beff69c255f6
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef nsSegmentedBuffer_h__
8 #define nsSegmentedBuffer_h__
10 #include "nsIMemory.h"
12 class nsSegmentedBuffer
14 public:
15 nsSegmentedBuffer()
16 : mSegmentSize(0)
17 , mMaxSize(0)
18 , mSegmentArray(nullptr)
19 , mSegmentArrayCount(0)
20 , mFirstSegmentIndex(0)
21 , mLastSegmentIndex(0)
25 ~nsSegmentedBuffer()
27 Empty();
31 nsresult Init(uint32_t aSegmentSize, uint32_t aMaxSize);
33 char* AppendNewSegment(); // pushes at end
35 // returns true if no more segments remain:
36 bool DeleteFirstSegment(); // pops from beginning
38 // returns true if no more segments remain:
39 bool DeleteLastSegment(); // pops from beginning
41 // Call Realloc() on last segment. This is used to reduce memory
42 // consumption when data is not an exact multiple of segment size.
43 bool ReallocLastSegment(size_t aNewSize);
45 void Empty(); // frees all segments
47 inline uint32_t GetSegmentCount()
49 if (mFirstSegmentIndex <= mLastSegmentIndex) {
50 return mLastSegmentIndex - mFirstSegmentIndex;
51 } else {
52 return mSegmentArrayCount + mLastSegmentIndex - mFirstSegmentIndex;
56 inline uint32_t GetSegmentSize()
58 return mSegmentSize;
60 inline uint32_t GetMaxSize()
62 return mMaxSize;
64 inline uint32_t GetSize()
66 return GetSegmentCount() * mSegmentSize;
69 inline char* GetSegment(uint32_t aIndex)
71 NS_ASSERTION(aIndex < GetSegmentCount(), "index out of bounds");
72 int32_t i = ModSegArraySize(mFirstSegmentIndex + (int32_t)aIndex);
73 return mSegmentArray[i];
76 protected:
77 inline int32_t ModSegArraySize(int32_t aIndex)
79 uint32_t result = aIndex & (mSegmentArrayCount - 1);
80 NS_ASSERTION(result == aIndex % mSegmentArrayCount,
81 "non-power-of-2 mSegmentArrayCount");
82 return result;
85 inline bool IsFull()
87 return ModSegArraySize(mLastSegmentIndex + 1) == mFirstSegmentIndex;
90 protected:
91 uint32_t mSegmentSize;
92 uint32_t mMaxSize;
93 char** mSegmentArray;
94 uint32_t mSegmentArrayCount;
95 int32_t mFirstSegmentIndex;
96 int32_t mLastSegmentIndex;
99 // NS_SEGMENTARRAY_INITIAL_SIZE: This number needs to start out as a
100 // power of 2 given how it gets used. We double the segment array
101 // when we overflow it, and use that fact that it's a power of 2
102 // to compute a fast modulus operation in IsFull.
104 // 32 segment array entries can accommodate 128k of data if segments
105 // are 4k in size. That seems like a reasonable amount that will avoid
106 // needing to grow the segment array.
107 #define NS_SEGMENTARRAY_INITIAL_COUNT 32
109 #endif // nsSegmentedBuffer_h__