我使用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