Vous ne pouvez pas allouer plus de 2^32. Mais vous pouvez réaffecter les poignées utilisées si elles sont libérées et le problème est de garder une trace des poignées libres.
Un arbre est un bon moyen de stocker les poignées libres. Chaque nœud a un handle le plus bas et un handle le plus haut, le sous-arbre de gauche contient les handles qui sont inférieurs au plus bas et le sous-arbre de droite contient les handles qui sont supérieurs au plus haut.
Un exemple est:
6-9
/\
2 15
/\
0 4
Si une poignée est relâchée, elle est stockée dans l'arbre. Par exemple, si 10 est libéré, l'arbre ressemble à:
6-10
/\
2 15
/\
0 4
Si la poignée 5 est libéré, vous pouvez choisir d'optimiser l'arbre parce que 4 peut être ajouté au noeud 5-10 comme wel:
5-10
/\
2 15
/\
0 4
pour:
4-10
/\
2 15
/
0
l'attribution d'une poignée, recherche un nœud feuille avec 1 poignée et il enlève de l'arbre. S'il n'y a pas de feuilles avec 1 poignée, il suffit d'utiliser une feuille et décrémenter le côté non connecté au parent:
4-10
/
1-2
Dans l'exemple ci-dessus nous allouons 1 et non 2 parce que si 3 est libéré, vous pouvez combinez-le avec 4 et vous voulez garder le nombre de nœuds aussi bas que possible.
Voici un algorithme de pseudocode. Certaines parties sont laissées au lecteur:
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;
Les poignées sont "désallouées" à un moment donné, et vous souhaitez pouvoir les réutiliser? –
Probablement, sinon la question n'a aucun sens. Si c'est le cas: Combien de poignées peuvent être attribuées en même temps? Je suis absolument sûr que ce ne sera pas 2^32. – gimpf
Par curiosité, avez-vous pensé à utiliser un LFSR? –