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
18 , mSegmentArray(nullptr)
19 , mSegmentArrayCount(0)
20 , mFirstSegmentIndex(0)
21 , mLastSegmentIndex(0)
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
;
52 return mSegmentArrayCount
+ mLastSegmentIndex
- mFirstSegmentIndex
;
56 inline uint32_t GetSegmentSize()
60 inline uint32_t GetMaxSize()
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
];
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");
87 return ModSegArraySize(mLastSegmentIndex
+ 1) == mFirstSegmentIndex
;
91 uint32_t mSegmentSize
;
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__