【问题标题】:How to sort IP addresses in a trie table?如何在 trie 表中对 IP 地址进行排序?
【发布时间】:2012-12-15 00:33:25
【问题描述】:

我想编写一些代码来在我的 Go 程序中创建一个小的“路由表”。

我正在使用带有http://github.com/petar/GoLLRB 包的左倾红黑树,基本上它似乎在使用它之后似乎可以工作,但是我怀疑我在创建时没有正确排序 IP 前缀那个树。我实验使用的“lessThan”函数是

func lessRoute(a, b interface{}) bool {
    aNet := a.(Route).Net
    bNet := b.(Route).Net

    for i, a := range aNet.IP {
        if a < bNet.IP[i] {
            return true
        }
        if a > bNet.IP[i] {
            return false
        }
    }
    return false
}

(完整代码在https://gist.github.com/4283789

这似乎给了我正确的结果,但不是很有效。

在我的测试中,我正在为

添加路线
AddRouteString(tree, "10.0.0.0/8", 10)
AddRouteString(tree, "10.20.0.0/16", 20)
AddRouteString(tree, "10.21.0.0/16", 21)

然后在查找 10.22.0.1 的路线时,它会在找到正确的结果之前查看 10.21.0.0/16 和 10.20.0.0/16。

我应该如何订购我的树以更快地找到正确的结果?

更新:@jnml 对如何更快地进行 IP 比较有一个很好的建议(也许这是我能做的最好的),但在我看来有办法利用前缀长度对树进行排序,以便可以在更少的步骤中找到匹配项。这就是我要找的。​​p>

【问题讨论】:

    标签: algorithm routing go binary-tree cidr


    【解决方案1】:

    我可能会写:

    if bytes.Compare([]byte(a), []byte(b)) < 0 {
            // ... whatever to do when address a < b (lexicographically)
    }
    

    或者对于树比较器:

    func lessRoute(a, b interface{}) bool {
            return bytes.Compare([]byte(a.(Route).Net.IP), []byte(b.(Route).Net.IP)) < 0
    }
    

    bytes.Compare() 记录了here

    【讨论】:

    • 啊,是的——这将使比较更快。不过,我关心的是如何订购这棵树;似乎也可以利用前缀长度。
    • 现代处理器会将整个 IP 地址拉入 L1 缓存并处理公共前缀的速度比您计算公共前缀的起始位置要快。
    猜你喜欢
    • 2011-10-02
    • 2016-03-04
    • 1970-01-01
    • 1970-01-01
    • 2012-11-25
    • 2011-09-09
    • 2020-01-10
    • 2011-05-21
    • 2017-06-24
    相关资源
    最近更新 更多