Commit 7b2b9654 authored by Max Kellermann's avatar Max Kellermann

util/SliceBuffer: use class HugeArray

parent c3cfa18e
...@@ -41,10 +41,7 @@ class SliceBuffer { ...@@ -41,10 +41,7 @@ class SliceBuffer {
T value; T value;
}; };
/** HugeArray<Slice> buffer;
* The maximum number of slices in this container.
*/
const unsigned n_max;
/** /**
* The number of slices that are initialized. This is used to * The number of slices that are initialized. This is used to
...@@ -58,39 +55,28 @@ class SliceBuffer { ...@@ -58,39 +55,28 @@ class SliceBuffer {
*/ */
unsigned n_allocated = 0; unsigned n_allocated = 0;
Slice *const data;
/** /**
* Pointer to the first free element in the chain. * Pointer to the first free element in the chain.
*/ */
Slice *available = nullptr; Slice *available = nullptr;
size_t CalcAllocationSize() const {
return n_max * sizeof(Slice);
}
public: public:
SliceBuffer(unsigned _count) SliceBuffer(unsigned _count)
:n_max(_count), :buffer(_count) {
data((Slice *)HugeAllocate(CalcAllocationSize()).data) { buffer.ForkCow(false);
assert(n_max > 0);
HugeForkCow(data, CalcAllocationSize(), false);
} }
~SliceBuffer() { ~SliceBuffer() {
/* all slices must be freed explicitly, and this /* all slices must be freed explicitly, and this
assertion checks for leaks */ assertion checks for leaks */
assert(n_allocated == 0); assert(n_allocated == 0);
HugeFree(data, CalcAllocationSize());
} }
SliceBuffer(const SliceBuffer &other) = delete; SliceBuffer(const SliceBuffer &other) = delete;
SliceBuffer &operator=(const SliceBuffer &other) = delete; SliceBuffer &operator=(const SliceBuffer &other) = delete;
unsigned GetCapacity() const { unsigned GetCapacity() const {
return n_max; return buffer.size();
} }
bool IsEmpty() const { bool IsEmpty() const {
...@@ -98,22 +84,22 @@ public: ...@@ -98,22 +84,22 @@ public:
} }
bool IsFull() const { bool IsFull() const {
return n_allocated == n_max; return n_allocated == buffer.size();
} }
template<typename... Args> template<typename... Args>
T *Allocate(Args&&... args) { T *Allocate(Args&&... args) {
assert(n_initialized <= n_max); assert(n_initialized <= buffer.size());
assert(n_allocated <= n_initialized); assert(n_allocated <= n_initialized);
if (available == nullptr) { if (available == nullptr) {
if (n_initialized == n_max) { if (n_initialized == buffer.size()) {
/* out of (internal) memory, buffer is full */ /* out of (internal) memory, buffer is full */
assert(n_allocated == n_max); assert(n_allocated == buffer.size());
return nullptr; return nullptr;
} }
available = &data[n_initialized++]; available = &buffer[n_initialized++];
available->next = nullptr; available->next = nullptr;
} }
...@@ -127,12 +113,12 @@ public: ...@@ -127,12 +113,12 @@ public:
} }
void Free(T *value) { void Free(T *value) {
assert(n_initialized <= n_max); assert(n_initialized <= buffer.size());
assert(n_allocated > 0); assert(n_allocated > 0);
assert(n_allocated <= n_initialized); assert(n_allocated <= n_initialized);
Slice *slice = reinterpret_cast<Slice *>(value); Slice *slice = reinterpret_cast<Slice *>(value);
assert(slice >= data && slice < data + n_max); assert(slice >= &buffer.front() && slice <= &buffer.back());
/* destruct the object */ /* destruct the object */
value->~T(); value->~T();
...@@ -145,7 +131,7 @@ public: ...@@ -145,7 +131,7 @@ public:
/* give memory back to the kernel when the last slice /* give memory back to the kernel when the last slice
was freed */ was freed */
if (n_allocated == 0) { if (n_allocated == 0) {
HugeDiscard(data, CalcAllocationSize()); buffer.Discard();
n_initialized = 0; n_initialized = 0;
available = nullptr; available = nullptr;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment