我使用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;
}
所以搜索是基于“结构nhlfe_key”,即比较功能 AVL树的样子这样的:
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树 不需要重建?)
我正在考虑在每个listnode上生成CRC,然后总结。这可以保证钥匙的唯一性吗? (缺点是,无论何时添加/删除listnode,我都必须重新生成密钥,从tre删除节点并用新密钥重新添加)。
谢谢!
Kaz,感谢您的评论,他们很有帮助。 – Mark 2012-04-05 12:10:16
但是,我不清楚生成密钥 - 现在我有一个IP地址列表,而不是像以前一样。我在考虑的一个解决方案是总是有一个基于列表的第一个元素的键(但是每当列表发生变化时,重新插入树中的节点)。是否有意义?或者可能有一个存储在列表中的IP哈希... – Mark 2012-04-05 12:20:20
我帮不了你。你正在试图决定两个键的平等意味着什么。关键的平等包括列表中的所有IP地址,还是仅基于第一个(其他是补充数据)?对象相等任意的定义(在任何相等必须满足的规则边界内)。选择是由应用程序所需的语义驱动的。如果你只把主要IP地址当作密钥,而不是其他的,那么只有你现在会破坏什么(如果有的话)。 – Kaz 2012-04-05 15:26:47