c++ - 确定性句柄分配算法

标签 c++ algorithm data-structures tree

我正在尝试找到一种有效的确定性方法来分配 32 位句柄,使其可以无限期地运行。一个简单的递增计数器将不起作用,因为它最终会循环。扩展到 64 位是不可能的,因为这些值将在需要 32 位值的网络协议(protocol)中使用。

它适用于实时系统,因此必须具有确定性和快速性。虽然它最终会出现在 SQLite 数据库中,但我不能在循环后暴力测试每个键,例如......

我想我需要的是某种范围树,它知道所有以前分配的句柄(在启动时填充它很好)。这似乎是一种常见的问题,但不是 boost 或 STL 可以解决的问题。

有什么建议吗?

编辑:一些额外的说明。我希望在任何时候在系统中拥有大约 200k 个事件句柄。句柄是随机删除的。

最佳答案

您不能分配超过 2^32。但是如果已使用的句柄被释放,您可以重新分配它们,问题是要跟踪空闲句柄。

树是存储空闲句柄的好方法。每个节点都有一个最低和最高句柄,左子树包含小于最低句柄的句柄,右子树包含大于最高句柄的句柄。

一个例子是:

            6-9
            / \
           2   15
          / \
         0   4

如果一个句柄被释放,它被存储在树中。例如,如果释放 10,则树看起来像:

            6-10
            / \
           2   15
          / \
         0   4

如果句柄 5 被释放,您可以选择优化树,因为 4 也可以添加到 5-10 节点:

            5-10
            / \
           2   15
          / \
         0   4

收件人:

            4-10
            / \
           2   15
          / 
         0  

一个句柄的分配,搜索一个有1个句柄的叶节点并将其从树中移除。如果没有带 1 个句柄的叶子,只需使用一个叶子并递减未连接到父节点的一侧:

         4-10
        /
      1-2

在上面的示例中,我们分配了 1 而不是 2,因为如果释放 3,您可以将它与 4 合并,并且您希望保持尽可能少的节点数。

下面是一个伪代码算法。部分内容留给读者:

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;

关于c++ - 确定性句柄分配算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1413193/

相关文章:

挑战 Node 语法

c++ - 在 Windows x64 上设置 openssl 时找不到 libeay32.lib 和 ssleay32.lib 文件

c++ - 如何让我的程序运行得更快?

c++ - 从函数返回 boost streambuf

c++ - Allegro draw_sprite()

java - 一种调度算法

algorithm - 使总和最小的元素?

c# - 平均特定数字的随机数

algorithm - 如何在 O(n) 时间内对双向链表进行二分查找?

c++ - 数据结构 : explanation of pop, push, dequeue, enqueue 在这类练习中