做 libantixunlei 扯出来的无聊技术之一

实际上就是一个数据结构而已,虽然偶觉得这个数据结构应该已经有人提出过了的说,但是找不到。偶把这个数据结构叫做哈希树,然后偶以哈希树为关键词查找,没找到多少结果。然后偶又以hash tree作为关键词查找,找到了维基百科,但是看上面的解释不太清楚,不过估计应该就是那样子的没错了。
弄出这个数据结构的初衷是想要保存一些FTP已登陆用户的信息,因为查找频繁,所以希望这个数据结构能提供很快的查找速度。于是想到了哈希表,但问题是,同时登陆的用户数是未知的,这样就不知道需要定义多大的哈希表,而且如果同时登陆的用户较多的话,哈希表也会变得比较大才能满足要求。
于是我就想,把平衡树挂在哈希表上,每一个哈希表的值节点都有挂着一颗平衡树。确定一个索引值在这个数据结构中的位置,首先进行哈希得到其位置,如果这个位置已经占用了,那么再进行最多2次哈希,如果在哈希表中找到空位,那么就把数据保存到哈希表中。如果2次哈希后都没有找到空位,就把数据插入到最后一次哈希得到的位置上面挂着的平衡树去。
当同时登陆的用户不多的时候,可以在接近O(1)的时间级上查找到一个用户的数据,而同时登陆的用户数多的时候,也不会占用太多内存空间,虽然查找时间退化成O(logn),但是这个n的增长和用户数的增长并不成一比一的线性。虽然就理论的时间复杂度来看复杂度还是这么多,但是应用到实际中时,也可以在比较大的数据量下实现几乎是O(1)的时间复杂度。因为增加的用户首先要丢到哈希表里面,如果哈希冲突才会丢到平衡树里面,而两个用户被丢到同一个平衡树里面的概率是很小的,仅仅是哈希表长度的倒数。理论上来说,如果哈希表长度是1000的话,平均每增加1000个用户,每一棵平衡树才会增加1个节点。考虑到实际是应用到FTP服务器的,这样算下来,就算同时登陆的用户有8000个,最多也只需要访问6次内存就可以查找到到指定的用户数据了。
想想以前那个反迅雷的Serv-U插件,偶偷工减料用链表来保存用户数据,哎呀如果是8000个用户的话那平均要访问4000次内存啊,那可真是糟糕的说。好吧就算用平衡树,平均也要访问13次内存的说,比哈希树慢了一倍多。
这只是做 libantixunlei 扯出来的数据结构之一,另外为了高效地根据FTP指令序列来判断谁是迅雷,还扯出了另外一个数据结构,下次再说了。

This entry was posted in 技术向 and tagged , , . Bookmark the permalink.

18 thoughts on “做 libantixunlei 扯出来的无聊技术之一

    • 实际上偶现在对IPv6还是无视的说 = =
      因为精打细算之后,大部分的访问最多也就几百一千多个并发,酱子开个几千的哈希表会更快的说,内存也就钉死吃几十KB而已,高效低耗的说
      几万的并发情况少……于是就丢到树里面了

  1. 啥意思,你可以用和hash一样大的那么多进制搞trie啊。。
    虽然不如hash平衡,浪费一点内存
    但是和指针有啥关系,hash你咋写的,就用啥方法不就行了?

  2. 这个东西。。如果那么肯浪费内存的话为什么不用trie,可以O(1)(按你这种计算方法的话。。)
    算法导论上有弄出很多个不同的hash函数的方法,就是为了这种东西准备的

    • 总感觉这个hakken用在这里是不对的说
      “发现”偶记得是有一个句型的说

      而且明明是上次你进后台玩过的说

  3. 怎么就只剩下拍死你了呢。。。前面还有一句呢。。。怎么给删了。。。唉唉~~~~肯定有不可告人的秘密~~~

发表评论

电子邮件地址不会被公开。

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>