reclaim destroyed arrival arrays
Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
parent
b06e72d61f
commit
2e89d12078
|
|
@ -527,7 +527,7 @@ void
|
||||||
Graph::deleteArrivals(Vertex *vertex,
|
Graph::deleteArrivals(Vertex *vertex,
|
||||||
uint32_t count)
|
uint32_t count)
|
||||||
{
|
{
|
||||||
arrivals_.deleteArray(count);
|
arrivals_.destroy(vertex->arrivals(), count);
|
||||||
vertex->setArrivals(arrival_null);
|
vertex->setArrivals(arrival_null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -557,7 +557,7 @@ void
|
||||||
Graph::deleteRequireds(Vertex *vertex,
|
Graph::deleteRequireds(Vertex *vertex,
|
||||||
uint32_t count)
|
uint32_t count)
|
||||||
{
|
{
|
||||||
arrivals_.deleteArray(count);
|
arrivals_.destroy(vertex->requireds(), count);
|
||||||
vertex->setRequireds(arrival_null);
|
vertex->setRequireds(arrival_null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string.h> // memcpy
|
#include <string.h> // memcpy
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "ObjectId.hh"
|
#include "ObjectId.hh"
|
||||||
#include "Error.hh"
|
#include "Error.hh"
|
||||||
|
|
@ -34,7 +35,8 @@ public:
|
||||||
void make(uint32_t count,
|
void make(uint32_t count,
|
||||||
TYPE *&array,
|
TYPE *&array,
|
||||||
ObjectId &id);
|
ObjectId &id);
|
||||||
void deleteArray(uint32_t count);
|
void destroy(ObjectId id,
|
||||||
|
uint32_t count);
|
||||||
// Grow as necessary and return pointer for id.
|
// Grow as necessary and return pointer for id.
|
||||||
TYPE *ensureId(ObjectId id);
|
TYPE *ensureId(ObjectId id);
|
||||||
TYPE *pointer(ObjectId id) const;
|
TYPE *pointer(ObjectId id) const;
|
||||||
|
|
@ -61,6 +63,8 @@ private:
|
||||||
size_t blocks_capacity_;
|
size_t blocks_capacity_;
|
||||||
ArrayBlock<TYPE>* *blocks_;
|
ArrayBlock<TYPE>* *blocks_;
|
||||||
ArrayBlock<TYPE>* *prev_blocks_;
|
ArrayBlock<TYPE>* *prev_blocks_;
|
||||||
|
// Linked list of free arrays indexed by array size.
|
||||||
|
std::vector<ObjectId> free_list_;
|
||||||
static constexpr ObjectId idx_mask_ = block_size - 1;
|
static constexpr ObjectId idx_mask_ = block_size - 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -98,17 +102,28 @@ ArrayTable<TYPE>::make(uint32_t count,
|
||||||
TYPE *&array,
|
TYPE *&array,
|
||||||
ObjectId &id)
|
ObjectId &id)
|
||||||
{
|
{
|
||||||
ArrayBlock<TYPE> *block = blocks_size_ ? blocks_[free_block_idx_] : nullptr;
|
// Check the free list for a previously destroyed array with the right size.
|
||||||
if ((free_idx_ == object_idx_null
|
if (count < free_list_.size()
|
||||||
&& free_block_idx_ == block_idx_null)
|
&& free_list_[count] != object_id_null) {
|
||||||
|| free_idx_ + count >= block->size()) {
|
id = free_list_[count];
|
||||||
uint32_t size = (count > block_size) ? count : block_size;
|
array = pointer(id);
|
||||||
block = makeBlock(size);
|
|
||||||
|
ObjectId *head = reinterpret_cast<ObjectId*>(array);
|
||||||
|
free_list_[count] = *head;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ArrayBlock<TYPE> *block = blocks_size_ ? blocks_[free_block_idx_] : nullptr;
|
||||||
|
if ((free_idx_ == object_idx_null
|
||||||
|
&& free_block_idx_ == block_idx_null)
|
||||||
|
|| free_idx_ + count >= block->size()) {
|
||||||
|
uint32_t size = (count > block_size) ? count : block_size;
|
||||||
|
block = makeBlock(size);
|
||||||
|
}
|
||||||
|
// makeId(free_block_idx_, idx_bits)
|
||||||
|
id = (free_block_idx_ << idx_bits) + free_idx_;
|
||||||
|
array = block->pointer(free_idx_);
|
||||||
|
free_idx_ += count;
|
||||||
}
|
}
|
||||||
// makeId(free_block_idx_, idx_bits)
|
|
||||||
id = (free_block_idx_ << idx_bits) + free_idx_;
|
|
||||||
array = block->pointer(free_idx_);
|
|
||||||
free_idx_ += count;
|
|
||||||
size_ += count;
|
size_ += count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -147,8 +162,17 @@ ArrayTable<TYPE>::pushBlock(ArrayBlock<TYPE> *block)
|
||||||
|
|
||||||
template <class TYPE>
|
template <class TYPE>
|
||||||
void
|
void
|
||||||
ArrayTable<TYPE>::deleteArray(uint32_t)
|
ArrayTable<TYPE>::destroy(ObjectId id,
|
||||||
|
uint32_t count)
|
||||||
{
|
{
|
||||||
|
if (count >= free_list_.size())
|
||||||
|
free_list_.resize(count + 1);
|
||||||
|
TYPE *array = pointer(id);
|
||||||
|
// Prepend id to the free list.
|
||||||
|
ObjectId *head = reinterpret_cast<ObjectId*>(array);
|
||||||
|
*head = free_list_[count];
|
||||||
|
free_list_[count] = id;
|
||||||
|
size_ -= count;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class TYPE>
|
template <class TYPE>
|
||||||
|
|
@ -199,6 +223,7 @@ ArrayTable<TYPE>::clear()
|
||||||
size_ = 0;
|
size_ = 0;
|
||||||
free_block_idx_ = block_idx_null;
|
free_block_idx_ = block_idx_null;
|
||||||
free_idx_ = object_idx_null;
|
free_idx_ = object_idx_null;
|
||||||
|
free_list_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue