xpcom/io/nsSegmentedBuffer.h

branch
TOR_BUG_9701
changeset 8
97036ab72558
equal deleted inserted replaced
-1:000000000000 0:7c854f16d394
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 #ifndef nsSegmentedBuffer_h__
7 #define nsSegmentedBuffer_h__
8
9 #include "nsIMemory.h"
10
11 class nsSegmentedBuffer
12 {
13 public:
14 nsSegmentedBuffer()
15 : mSegmentSize(0), mMaxSize(0),
16 mSegmentArray(nullptr),
17 mSegmentArrayCount(0),
18 mFirstSegmentIndex(0), mLastSegmentIndex(0) {}
19
20 ~nsSegmentedBuffer() {
21 Empty();
22 }
23
24
25 nsresult Init(uint32_t segmentSize, uint32_t maxSize);
26
27 char* AppendNewSegment(); // pushes at end
28
29 // returns true if no more segments remain:
30 bool DeleteFirstSegment(); // pops from beginning
31
32 // returns true if no more segments remain:
33 bool DeleteLastSegment(); // pops from beginning
34
35 // Call Realloc() on last segment. This is used to reduce memory
36 // consumption when data is not an exact multiple of segment size.
37 bool ReallocLastSegment(size_t newSize);
38
39 void Empty(); // frees all segments
40
41 inline uint32_t GetSegmentCount() {
42 if (mFirstSegmentIndex <= mLastSegmentIndex)
43 return mLastSegmentIndex - mFirstSegmentIndex;
44 else
45 return mSegmentArrayCount + mLastSegmentIndex - mFirstSegmentIndex;
46 }
47
48 inline uint32_t GetSegmentSize() { return mSegmentSize; }
49 inline uint32_t GetMaxSize() { return mMaxSize; }
50 inline uint32_t GetSize() { return GetSegmentCount() * mSegmentSize; }
51
52 inline char* GetSegment(uint32_t indx) {
53 NS_ASSERTION(indx < GetSegmentCount(), "index out of bounds");
54 int32_t i = ModSegArraySize(mFirstSegmentIndex + (int32_t)indx);
55 return mSegmentArray[i];
56 }
57
58 protected:
59 inline int32_t ModSegArraySize(int32_t n) {
60 uint32_t result = n & (mSegmentArrayCount - 1);
61 NS_ASSERTION(result == n % mSegmentArrayCount,
62 "non-power-of-2 mSegmentArrayCount");
63 return result;
64 }
65
66 inline bool IsFull() {
67 return ModSegArraySize(mLastSegmentIndex + 1) == mFirstSegmentIndex;
68 }
69
70 protected:
71 uint32_t mSegmentSize;
72 uint32_t mMaxSize;
73 char** mSegmentArray;
74 uint32_t mSegmentArrayCount;
75 int32_t mFirstSegmentIndex;
76 int32_t mLastSegmentIndex;
77 };
78
79 // NS_SEGMENTARRAY_INITIAL_SIZE: This number needs to start out as a
80 // power of 2 given how it gets used. We double the segment array
81 // when we overflow it, and use that fact that it's a power of 2
82 // to compute a fast modulus operation in IsFull.
83 //
84 // 32 segment array entries can accommodate 128k of data if segments
85 // are 4k in size. That seems like a reasonable amount that will avoid
86 // needing to grow the segment array.
87 #define NS_SEGMENTARRAY_INITIAL_COUNT 32
88
89 #endif // nsSegmentedBuffer_h__

mercurial