什么是Aguri树?


19

浏览一些旧的Hacker News文章时,我遇到了一个用户的帖子,内容是

Aguri树,这些树将有界大小的基数trie(例如您将在软件路由表中使用)嫁接到LRU列表,并自动从模式中合成聚合(例如来自所有IP的1000个观察值的10.0.0.0/16)插入。它们在流量分析中最为人所知,但我们也在运行时内存分析中也使用了它们。

tptacek

所以我决定查一下

  • 快速的Google搜索将我带到F1驱动程序。
  • 在Wikipedia上进行搜索会导致印度出现种姓制度,而日本也有一些商品
  • 堆栈溢出命中0个结果/programming//search?q=aguri site:stackoverflow.com/questions aguri

所以我终于将其链接回用户,看到他的博客上有链接

http://www.matasano.com/log/1009/aguri-coolest-data-structure-youve-never-heard-of/

但这已经死了。

那么,这个Aguri数据结构是什么?如果它是真实的数据结构,为什么在其他任何地方都没有记录呢?

Answers:


15

Aguri是使用前缀树的流量分析器。在完整的文章是在该网页。简而言之,除非您将该系统中使用的前缀树视为它们自己的唯一子类型,否则就没有“ Aguri树”这样的数据结构。


9

很少有人真正死在互联网上。Archive.org恰好只有该博客文章上线的一个快照。复制在这里:

面向读者的PCI计算机审计人员的一些补救性计算机科学。

我给你一个随机整数数组。你怎么知道第三位在里面?

好吧,有一个明显的方法:顺序检查数字,直到找到“ 3”或用尽数组。线性搜索。给定10个数字,您必须假设它可以采取10个步骤;N个数字,N步。

图片1.png

线性搜索不好。很难做得比线性还差。让我们对其进行改进。对数组进行排序。

图片2.png

排序后的数组建议采取另一种策略:跳到数组的中间,查看您要查找的值是小于(左侧)还是大于(右侧)。重复,每次将数组切成两半,直到找到该值。

二进制搜索。给定10个数字,最多需要3个步骤-log2 of 10-在排序数组中找到其中一个。O(log n)搜索很棒。如果您有65,000个元素,则只需16个步骤即可找到其中一个元素。将元素加倍,这是17个步骤。

但是排序的数组很烂;一方面,排序要比线性搜索昂贵。因此,我们不会过多地使用二进制搜索。相反,我们使用二叉树。

图片3.png

要搜索二叉树,请从顶部开始,然后问自己“我的密钥是否小于(当前)(左)或大于(当前)(右)”,然后重复进行直到确定,确定,确定,您已经知道了这些内容。但是那棵树很漂亮,不是吗?

用(平衡)二叉树进行搜索是O(log n),就像二叉搜索一样,随树中元素的数量而变化。二进制树很棒:您可以快速查找和排序遍历,而哈希表中却没有。与哈希表相比,二叉树是更好的默认表实现。2。

但是,二叉树并不是唯一的树型查找机制。二进制基数尝试(也称为PATRICIA树)的工作方式与具有基本区别的二进制树相似。而不是比较每个节点的大于/小于-,而是检查是否设置了某个位,如果设置了,则向右分支,如果未设置,则向左分支。

图片4.png

关于二进制基数如何工作,我遗漏了很多。这真是太可惜了,因为众所周知,基数尝试没有得到充分记录-Sedgewick在“算法”中臭名昭著地将它们搞砸了,而维基百科上的页面糟透了。人们仍然在争论如何称呼他们!代替对反向链接和标有位置标记的边缘的解释,这是一个很小的Ruby实现。

这就是为什么基数尝试很酷的原因:

Search performance varies with the key size, not the number of elements in the tree. With 16 bit keys, you’re guaranteed 16 steps

无论树中元素的数量如何,都无法保持平衡。

More importantly, radix tries give you lexicographic matching, which is a puffed-up way of saying “search with trailing wildcard”, or

“命令行补全样式搜索”。在基数树中,您可以快速搜索“ ro *”并获得“ rome”,“ romulous”和“ roswell”。

3。

我迷路了

让我们将其放在上下文中。尝试是Internet路由的关键数据结构。路由问题如下:

You have a routing table with entries for “10.0.1.20/32 -> a” and “10.0.0.0/16 -> b”.

You need packets for 10.0.1.20 to go to “a”

You need packets for 10.0.1.21 to to to “b”

对于基本的二叉树来说,这是一个很难解决的问题,但是对于基数树,您只要求“ 1010.0000.0000.0000.0000.0001.01.0”(对于10.0.1.20)和“ 1010”(对于10.0.0.0)。 )。词典搜索为您提供“最佳匹配”路由选择。您可以在上面的Ruby代码中尝试一下;将*“ 10.0.0.0” .to_ip添加到特里,并搜索“ 10.0.0.1” .to_ip。

路由和基数尝试之间的对应关系是如此之强,以至于最流行的通用基数特里库(实际上是CPAN的库)实际上是从GateD中偷走的。顺便说一句,这是一团糟,不要使用它。

如果您了解Trie的工作原理,那么您还将了解正则表达式的工作原理。尝试是确定性有限自动机(DFA)的一种特殊情况,其中分支完全基于位比较,并且始终分支向前。一个好的正则表达式引擎只会处理具有更多“功能”的DFA。如果我的图片对您有意义,那么这篇关于汤普森的NFA-DFA缩减算法的出色文章中的图片也将使您变得更聪明。4。

您是骨干ISP的网络运营商。您的世界主要由“前缀”组成-IP网络/网络掩码对。这些前缀中的网络掩码对您非常重要。例如121/8属于韩国;121.128 / 10属于Korea Telecom,121.128.10 / 24属于KT客户,121.128.10.53是该客户内部的一台计算机。如果您要跟踪僵尸网络,垃圾邮件操作或蠕虫传播,那么该网络掩码号对您来说非常重要。

不幸的是,尽管很重要,但IP数据包上没有标记“网络掩码”-网络掩码完全是配置细节。因此,当您观看流量时,实际上可以使用以下数据:

ips.png

令人惊讶的是,如果有足够的数据包可以查看,那么就足以猜测网络掩码了。在索尼工作期间,赵健次郎基于尝试,提出了一种非常优雅的方法。这是如何做:

就像软件路由器使用的一样,采用基本的二进制基数trie。但是将树中的节点数限制为10,000。在主干链路上,记录IP标头中的地址,您将立即耗尽10,000个节点。

将节点列表存储在按LRU顺序排序的列表中。换句话说,当您将IP地址与节点匹配时,“触摸”该节点,并将其粘贴在列表的顶部。逐渐地,经常看到的地址冒泡到顶部,而很少看到的节点沉入底部。

图片6.png

现在的把戏。当节点用完并需要一个新节点时,请从列表底部收回。但是当您这样做时,将数据从节点向上滚动到其父节点,如下所示:

图片5.png

10.0.1.2和10.0.1.3是同级/ 32,即两半10.0.1.2/31。要回收它们,请将它们合并为10.0.1.2/31。如果需要回收10.0.1.2/31,则可以将其与10.0.1.0/31合并为10.0.1.0/30。

这样做需要一分钟,然后杰出的信号源将停留在LRU列表的顶部,从而捍卫它们在树中的位置,而周围的/ 32噪声气泡高达/ 0。对于上面的IP的原始列表,带有100个节点树,您可以得到此列表。

Cho称之为启发式Aguri。5,

Aguri已获得BSD许可。您可以从Cho的旧主页下载它,以及可以通过pcap监视数据包的驱动程序。6。

我要去这个地方,但现在我在这篇文章中写了1300个字,如果您是算法专家,那么现在您已经厌倦了我,如果您不是算法专家,那么您现在已经厌倦了我现在。因此,让Aguri投入其中,本周晚些时候,我将为您提供一些无用的有趣功能。

那里有许多链接。不幸的是,Archive.org并不保留图像,而仅保留文本,因此其中一些丢失了。这是它已存档的文件:


这确实显示了信息,是否有任何原因导致所有这些链接不再可用?
phwd 2012年

@phwd我只是复制/粘贴了Wayback Machine链接到的底部的链接。并且它链接到自身,因此您在撰写博客文章时会看到这些页面。我知道Wikipedia文章和正则表达式比较仍然存在。
Izkata 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.