β

RabbitMQ源码之dtree.erl

Roowe❤ 230 阅读

dtree.erl

代码里面一堆gb_trees和gb_sets的操作,也算是学习gb_trees和gb_sets的操作的典范。

这是双键的数据结构,若干条如下的记录。

%% +----+--------------------+---+
%% | PK | SK1, SK2, ..., SKN | V |
%% +----+--------------------+---+

大概这样的数据结构主要是用来处理如下的需求,每个消息要接收之后要存储和转发到不同的地方。大概的数据结构就是{MsgId, QueueSet, Msg}。

先讲take的相关的接口,这个接口有take(PKs, SK, {P, S})和take(SK, {P, S}),前者可以理解成从{P, S}取回队列属于SK并且在MsgId在PKs里面的[{MsgId_1, Msg_1}, …,{MsgId_n, Msg_n}],后者可以理解成从{P, S}取回队列属于SK的[{MsgId_1, Msg_1}, …,{MsgId_n, Msg_n}]

接着还有个take_all(SK, {P, S}),就是通过SK取出所有的PKs,然后根据PKs返回所有。

上面的take实际是等于select_delete的。

知道查询,就看下insert,存储那块有两个gb_trees,一个维护Pri,一个维护SecondKey映射到PriKeys,PriKeys由gb_sets存储,说起来基本就这么简单。

如果不明白,可以看下相关阅读3那份文档,看完也大概知道这结构究竟是为什么需求服务的。

我一开始也觉得想设计简单的话,像{Pri, Second, Msg}一个信息要Len(QueueList)条,最后变成了Len(QueueList_1)+…+Len(QueueList_n),n是Len(Pri)。如果是上面的数据结构的话,Len(Pri)+Len(所有QueueList)。数据会有很多冗余,性能也上不去。

作者:Roowe❤
33.3% Linux 33.3% Mathematics 33.3% Inspiration
原文地址:RabbitMQ源码之dtree.erl, 感谢原作者分享。

发表评论