8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 10:03:03 +01:00

Totally misc.

This commit is contained in:
robocop 2008-03-08 11:32:11 +00:00
parent 21a1eed8a1
commit 812058f940

View File

@ -61,7 +61,8 @@ const int NODE_PAGE_SIZE = 3000;
// should be more than enough. No checks are performed in code against overflow of this value
const int MAX_TREE_LEVEL = 30;
class MallocAllocator {
class MallocAllocator
{
public:
void *allocate(size_t size) {
return malloc(size);
@ -103,9 +104,10 @@ template <typename Value, typename Key = Value, typename Allocator = MallocAlloc
typename Cmp = DefaultComparator<Key>,
int LeafCount = LEAF_PAGE_SIZE / sizeof(Value),
int NodeCount = NODE_PAGE_SIZE / sizeof(void*)>
class BePlusTree {
class BePlusTree
{
public:
BePlusTree(Allocator *_pool)
explicit BePlusTree(Allocator *_pool)
: pool(_pool), level(0), root(NULL), defaultAccessor(this)
{ }
@ -119,13 +121,15 @@ public:
append(from);
}
BePlusTree& operator =(BePlusTree& from) {
BePlusTree& operator =(BePlusTree& from)
{
clear();
append(from);
return *this;
}
void clear() {
void clear()
{
defaultAccessor.curr = NULL;
// Do not deallocate root page if tree is shallow
@ -168,12 +172,14 @@ public:
level = 0;
}
~BePlusTree() {
~BePlusTree()
{
clear();
pool->deallocate(root);
}
bool isEmpty() const {
bool isEmpty() const
{
return
root == NULL ||
(level == 0 && ((ItemList*)root)->getCount() == 0);
@ -209,7 +215,8 @@ public:
Value& current() const { return defaultAccessor.current(); }
// Returns true if this tree appears to contain more elements than the other
bool seemsBiggerThan(const BePlusTree &other) const {
bool seemsBiggerThan(const BePlusTree &other) const
{
if (level != other.level)
return level > other.level;
@ -225,11 +232,13 @@ public:
}
// Compute approximate number of leafs in the tree
size_t approxCount() const {
size_t approxCount() const
{
if (!root)
return 0;
if (level == 0) return ((ItemList*)root)->getCount();
if (level == 0)
return ((ItemList*)root)->getCount();
// Tree is large. Roughtly estimate number of leaf nodes using number of
// items in root list and depth of the tree. Theoretically possible fill
@ -245,7 +254,8 @@ public:
}
// Compute approximate memory consumption for tree in bytes
size_t approxSize() const {
size_t approxSize() const
{
if (!root)
return 0;
@ -263,7 +273,8 @@ public:
return ((NodeList*)root)->getCount() * bytes_per_node;
}
void append(BePlusTree& from) {
void append(BePlusTree& from)
{
// This is slow approach especially when used for assignment.
// Optimize it when need arises.
Accessor accessor(&from);
@ -285,12 +296,15 @@ public:
#endif
class NodeList;
class ItemList : public SortedVector<Value, LeafCount, Key, KeyOfValue, Cmp> {
class ItemList : public SortedVector<Value, LeafCount, Key, KeyOfValue, Cmp>
{
public:
NodeList *parent;
ItemList *next, *prev;
// Adds newly created item to doubly-linked list
ItemList(ItemList *items) : parent(NULL) {
ItemList(ItemList *items)
: parent(NULL)
{
if ((next = items->next))
next->prev = this;
prev = items;
@ -306,10 +320,13 @@ public:
#endif
};
class NodeList : public SortedVector<void*, NodeCount, Key, NodeList, Cmp> {
class NodeList : public SortedVector<void*, NodeCount, Key, NodeList, Cmp>
{
public:
// Adds newly created item to the doubly-linked list
NodeList(NodeList *items) : parent(NULL) {
NodeList(NodeList *items)
: parent(NULL)
{
if ((next = items->next))
next->prev = this;
prev = items;
@ -330,7 +347,8 @@ public:
// add ItemList typedef for you compiler with whichever syntax it likes
return KeyOfValue::generate(item, *((ItemList *)item)->begin());
}
static void setNodeParentAndLevel(void *node, int level, NodeList *parent) {
static void setNodeParentAndLevel(void *node, int level, NodeList *parent)
{
if (level) {
((NodeList *)node)->parent = parent;
((NodeList *)node)->level = level - 1;
@ -338,7 +356,8 @@ public:
else
((ItemList *)node)->parent = parent;
}
static void setNodeParent(void *node, int level, NodeList *parent) {
static void setNodeParent(void *node, int level, NodeList *parent)
{
if (level)
((NodeList *)node)->parent = parent;
else
@ -347,17 +366,20 @@ public:
};
public:
class Accessor {
class Accessor
{
public:
Accessor(BePlusTree* _tree) : curr(NULL), curPos(0), tree(_tree) {}
explicit Accessor(BePlusTree* _tree) : curr(NULL), curPos(0), tree(_tree) {}
bool add(const Value& item) {
bool add(const Value& item)
{
return tree->add(item, this);
}
// Remove item. Current position moves to next item after this call.
// If next item doesn't exist method returns false
bool fastRemove() {
bool fastRemove()
{
// invalidate current position of defaultAccessor
// if i'm not a defaultAccessor
if (this != &tree->defaultAccessor)
@ -425,17 +447,21 @@ public:
return true;
}
bool locate(const Key& key) {
bool locate(const Key& key)
{
return locate(locEqual, key);
}
// Position accessor on item having LocType relationship with given key
// If method returns false position of accessor is not defined.
bool locate(LocType lt, const Key& key) {
bool locate(LocType lt, const Key& key)
{
// Inlining is efficient here because LocType will be known in most cases
// and compiler will be able to eliminate most of code
void *list = tree->root;
if (!list) return false; // Uninitalized tree
if (!list)
return false; // Uninitalized tree
for (int lev = tree->level; lev; lev--) {
size_t pos;
if (!((NodeList *)list)->find(key, pos))
@ -483,10 +509,12 @@ public:
}
// If method returns false it means list is empty and
// position of accessor is not defined.
bool getFirst() {
bool getFirst()
{
void *items = tree->root;
if (!items)
return false; // Uninitalized tree
for (int i = tree->level; i > 0; i--)
items = (*(NodeList *)items)[0];
curr = (ItemList *)items;
@ -495,10 +523,12 @@ public:
}
// If method returns false it means list is empty and
// position of accessor is not defined.
bool getLast() {
bool getLast()
{
void *items = tree->root;
if (!items)
return false; // Uninitalized tree
for (int i = tree->level; i > 0; i--)
items = (*(NodeList *)items)[((NodeList *)items)->getCount() - 1];
curr = (ItemList *)items;
@ -510,7 +540,8 @@ public:
}
// Accessor position must be establised via successful call to getFirst(),
// getLast() or locate() before you can call this method
bool getNext() {
bool getNext()
{
curPos++;
if (curPos >= curr->getCount()) {
if (curr->next) {
@ -527,7 +558,8 @@ public:
}
// Accessor position must be establised via successful call to getFirst(),
// getLast() or locate() before you can call this method
bool getPrev() {
bool getPrev()
{
if (curPos == 0) {
if (curr->prev) {
curr = curr->prev;