You can't allocate more than 2^32. But you can reallocate used handles if they are released and the problem is to keep track of the free handles.
A tree is a good way to store the free handles. Each node has a lowest and a highest handle, the left subtree contains the handles that are lesser than the lowest and the right subtree contains the handles that are greater than the highest.
An example is:
6-9
/ \
2 15
/ \
0 4
If a handle is released, it is stored in the tree. For example, if 10 is released, the tree looks like:
6-10
/ \
2 15
/ \
0 4
If handle 5 is released, you can chose to optimize the tree because 4 can be added to the 5-10 node as wel:
5-10
/ \
2 15
/ \
0 4
To:
4-10
/ \
2 15
/
0
The allocation of a handle, searches for a leaf node with 1 handle and removes it from the tree. If there are no leaves with 1 handle, just use a leaf and decrement the side that is not connected to the parent:
4-10
/
1-2
In the above example we allocate 1 and not 2 because if 3 is released, you can combine it with 4 and you want to keep the number of nodes as low as possible.
Below is a pseudocode algorithm. Some parts are left for the reader:
Node = ( int lowest, highest; [Node] left, right)
Node.Allocate()
if TryFindLonelyLeaf(handle) return handle;
else
return FindLeafHandle(NULL);
Node.TryFindLonelyLeaf(handle)
if (left == NULL & right == NULL)
if (lowest == highest)
handle == lowest;
return TRUE;
else
return FALSE;
if (left != NULL & left.TryFindLonelyLeaf(handle))
if (left.lowest == handle)
left == NULL; // Free node
return TRUE;
elsif (right != NULL & right.TryFindLonelyLeaf(handle))
if (right.lowest == handle)
right = NULL; // Free node
return TRUE;
else
return FALSE;
Node.FindLeafHhandle(parent)
if (left == NULL & right == NULL)
if (parent == NULL | parent.right == this)
handle = lowest;
lowest++;
else
handle = highest;
highest--;
return handle;
else if (left != NULL)
return left.FindLeafHandle();
else // right != NULL
return right.FindLeafHandle();
Node.DeAllocate(handle)
Assert(handle<lowest or handle>highest);
if (handle == lowest-1)
lowest = CompactLeft(handle);
elsif (handle == lowest+1)
highest = CompactRight(handle);
elsif (handle<lowest)
if (left == NULL)
left = (handle, handle, NULL, NULL);
else
left.DeAllocate(handle);
elsif (handle>highest)
if (right == NULL)
right = (handle, handle, NULL, NULL);
else
right.DeAllocate(handle);
else ERROR
Node.CompactLeft(handle)
if (highest == handle-1)
handle = lowest;
// deallocate node and replace with left subtree
return handle;
elsif (right != NULL)
return right.CompactLeft(handle)
else
return handle;
Node.CompactRight(handle)
if (lowest == handle+1)
handle = highest;
// deallocate node and replace with right subtree
return handle;
elsif (left != NULL)
return left.CompactRight(handle)
else
return handle;