util/SliceBuffer: use class HugeArray

This commit is contained in:
Max Kellermann 2017-09-21 21:29:42 +02:00
parent c3cfa18ebe
commit 7b2b965415
1 changed files with 12 additions and 26 deletions

View File

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