Ternary Search Trees
bearophile
bearophileHUGS at lycos.com
Sat Apr 18 11:34:29 PDT 2009
This is the final version I am added to the dlibs:
/********************************************
To create a memory pool of a native item, like structs. Not thread-safe.
It allows to create new items (it performs block-allocations for speed), and then
free them all at once (and then you can create some more).
*/
struct MemoryPool(T, int MAX_BLOCK_BYTES=1 << 14) {
static assert(!is(T == class), "MemoryPool is designed for native data, not classes.");
static assert(MAX_BLOCK_BYTES >= 1,
"MemoryPool: MAX_BLOCK_BYTES must be >= 1 bytes.");
struct Block {
static assert(MAX_BLOCK_BYTES >= T.sizeof,
"MemoryPool: MAX_BLOCK_BYTES must be bigger than a T.");
static if ((T.sizeof * 5) > MAX_BLOCK_BYTES)
pragma(msg, "MemoryPool: Block is very small, so probably a MemoryPool isn't useful.");
T[(MAX_BLOCK_BYTES / T.sizeof)] items;
}
static Block*[] blocks;
static T* nextFree, lastFree; // a single int that keeps the number of items used
// in the last block is enough, but it may lead to a
// bit slower code.
/// Return pointer to a new item. Allocates memory if necessary.
static T* newItem() {
if (nextFree >= lastFree) { // then add new block.
// this whole new block gets scanned by the GC,
// even if you need only 1 item
blocks.length = blocks.length + 1;
blocks[$-1] = new Block;
nextFree = blocks[$-1].items.ptr;
lastFree = nextFree + Block.items.length;
}
return nextFree++;
}
/// Deallocate all items at once. You can then create new ones.
static void freeAll() {
foreach (block_ptr; blocks)
delete block_ptr;
blocks[] = null;
blocks.length = 0;
nextFree = null;
lastFree = null;
}
// This is like free() but doesn't deallocate memory, just cleans it up so
// when you create new items there's no new memory allocation, and it's
// faster. But to implement this other static members seem necessary.
//static void cleanMemory() {
//}
} // end of MemoryPool!()
unittest { // tests of MemoryPool!()
struct BinaryTreeNode {
BinaryTreeNode* left, right;
int data;
string toString() {
string nrepr(BinaryTreeNode* n) { return n is null ? "nil" : str(*n); }
return "<" ~ str(data) ~ ", " ~ nrepr(left) ~ ", " ~ nrepr(right) ~ ">";
}
}
MemoryPool!(BinaryTreeNode) BinaryTreeNodePool;
auto t = BinaryTreeNodePool.newItem();
t.data = 100;
t.left = BinaryTreeNodePool.newItem();
t.left.data = 7;
t.right = BinaryTreeNodePool.newItem();
t.right.data = 150;
assert(str(*t) == "<100, <7, nil, nil>, <150, nil, nil>>");
} // end tests of MemoryPool!()
More information about the Digitalmars-d
mailing list