util/SliceBuffer: use class HugeArray
This commit is contained in:
@@ -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 {
|
|||||||
*/
|
*/
|
||||||
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:
|
|||||||
}
|
}
|
||||||
|
|
||||||
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:
|
|||||||
}
|
}
|
||||||
|
|
||||||
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:
|
|||||||
/* 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;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user