繁体   English   中英

为 AVL 树生成密钥

[英]generating key for AVL tree

我有一个使用 AVL 树快速搜索 IP 地址的大型系统:

struct avl_node
{
   struct avl_node *left;
   struct avl_node *right;
   ...
   void *info; /* point to nhlfe_entry describing nexthop */
}

struct nhlfe_entry
{
  u_int32_t nhlfe_ix;
  u_char opcode;
  ...
  struct nhlfe_key key;
}

/* defines a search key. */
struct nhlfe_key
{
  struct in_addr nh_addr;
  u_int32_t oif_ix;
  u_int32_t out_label;
}

所以搜索是基于“struct nhlfe_key”,即 AVL 树中的比较器 function 如下所示:

static int
mpls_cmp_nhlfe_ipv4_key (void *data1, void* data2)
{
   struct nhlfe_entry *nh1, *nh2;
   struct nhlfe_key *key1, *key2;
   int ret;

   nh1 = (struct nhlfe_entry *) data1;
   nh2 = (struct nhlfe_entry *) data2;

   key1 = (struct nhlfe_key *) nh1->nkey;
   key2 = (struct nhlfe_key *) nh2->nkey;

   ret = memcmp (&key1->nh_addr, &key2->nh_addr, sizeof (struct in_addr));
   if (ret != 0)
     return ret;

   if (key1->oif_ix > key2->oif_ix)
     return 1;
   else if (key1->oif_ix < key2->oif_ix)
     return -1;

   if (key1->out_label > key2->out_label)
     return 1;
   else if (key1->out_label < key2->out_label)
     return -1;

   return 0;
}

现在,我要做的是添加对多个下一跳的支持,即我在 nhlfe_entry 中添加一个链表:

struct nhlfe_entry
{
  u_int32_t nhlfe_ix;
  u_char opcode;
  ...
  struct list *nhkey_list;
}

每个'struct list'都是struct listnode,它嵌入'void *data'指向调用者私有数据的指针,这就是'struct nhlfe_key'。

所以我的问题是——如何根据列表中的多个元素生成密钥以在树中存储/搜索节点(因为否则现在在引入列表后,将不可能仅基于一个下一跳来获得密钥地址)。 此外,他们同样的问题适用于搜索。

另外,在列表中添加新节点后,是否需要重新构建树,因为我认为此操作会更改密钥,因此树可能会变得不平衡? (或者具有正确实现的 AVL 树自然不需要重建?)

我正在考虑在每个列表节点上生成 CRC,然后求和。 这样能保证key的唯一性吗? (缺点是每当我添加/删除列表节点时,我都必须重新生成密钥,从 tre 中删除节点并使用新密钥重新添加)。

谢谢!

我有一个使用 AVL 树快速搜索 IP 地址的大型系统:

对于大量 IP 地址,您通常需要基数树。 二叉树可以工作,但您没有任何能力使用前缀存储地址范围,例如10.* 如果您不将此用于类似路由的任何事情,或者您不需要节省将整个 su.net 映射到某物的空间。

所以我的问题是——如何根据列表中的多个元素生成密钥以在树中存储/搜索节点(因为否则现在在引入列表后,将不可能仅基于一个下一跳来获得密钥地址)。 此外,他们同样的问题适用于搜索。

您的mpls_cmp_nhlfe_ipv4_key function 将只需要比较可能是地址列表的键。 显然(1 2 3)比较等于(1 2 3) 此外, (1 2 3)比较大于(1 2) ,但小于(1 3)(1 2 4)

另外,在列表中添加新节点后,我是否需要重新构建树...

如果要更新平衡搜索树中的节点以致键发生变化,最好的办法可能是将其删除并重新插入。

可能有优化它的方法。 例如,假设一个键改变了,但它在树中仍然有完全相同的后继者和前任者。 那样的话,原地做就好了。 或者一个密钥可以以这样一种方式改变,即一个节点只需要与前任或后继交换。 在尝试这样的技巧之前,我会做对的。

[CRC] 能否保证密钥的唯一性?

不,CRC 是散列 function。它的位数少于被散列的 object,因此多个对象可以 hash 到同一个 CRC。 (例外情况是为一组元素找到“完美散列函数”,但动态数据很少发生这种情况:完美散列函数是为某些 static 数据集设计的。)使用散列方法,您可能我们将使用 hash 表。 CRC 的排序关系可能毫无意义。 当必须通过键的排序关系对集合进行排序时,使用二叉搜索树。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM