本文由逍遥子撰写。转发请标注原址:

http://blog.csdn.net/houjixin/article/details/46413783



http://houjixin.blog.163.com/blog/static/35628410201558423159/

8.1  mosquitto的订阅树机制

在mosquitto原始版本号中。全部的订阅关系都是通过一颗订阅树来维护,在订阅树中,topic将被依照“/”组织成树状结构,如图5-3所看到的的订阅树,当中订阅树的每一个节点都是一个topic分级,每一个节点相应的topic就是从根节点到当前节点所组成的topic,每一个节点旁边的星状列表即是该节点所相应的订阅列表。

图8-1 订阅树

在mosquitto原始版本号程序中,订阅树依照topic来搭建,topic的数量和分级形式直接决定了订阅树的形状,进而影响操作效率。在mosquitto中。对上述订阅树的操作主要是查询、插入和删除操作,上述操作都涉及对订阅树的遍历。

以插入操作为例,将topic各分级的内容与订阅树的各层节点相比較,依此找到相匹配的节点,假设找到,则继续下一级匹配。直到订阅的topic所有匹配成功,此时仅仅需将context挂到订阅树的当前节点的订阅列表中就可以;假设匹配过程中有topic分级的内容无法匹配成功。则说明订阅树中尚不存在所订阅的topic,此时需将topic分级中不匹配的节点增加到订阅树中,并将context挂到新生成节点的订阅列表中。比如,假设一个新的clientcontext1订阅了topic:a1/b1/c1,则mosquitto内部首先将topic依照“/”切割为a1、b1、c1三级列表。然后以递归方式将topic列表中的内容与订阅树中各节点的内容进行匹配。详细匹配过程为:

假设topic列表中当前分级的内容不为空。且与订阅树中节点的内容相匹配的,则继续选择topic列表中的下一个分级内容,与订阅树中当前节点的子树进行相同的匹配。

假设topic列表中当前分级内容不为空,且订阅树的当前层中没有找到与分级内容想匹配的节点,则为topic的该分级新增一个节点;继续以该新增节点为子树的根节点进行匹配。

假设topic列表为空,则将其挂到相应订阅树的当前节点相应的订阅列表中;

图8-2即为上述匹配过程的流程图。

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaG91aml4aW4=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

图8-2 订阅树的匹配流程

8.2、  订阅机制的优化

Mosquitto的原来对订阅着的组织採用树形结构。这样的方式的长处是在逻辑上比較清晰,可是其插入、查找和删除的效率较低。

针对mosquitto订阅树的这样的缺陷,本次优化过程将去掉订阅树,採用hash表的方式存储各topic及其订阅列表。hash表的方式主要是为了通过topic高速定位到其订阅列表,因此,hash表的value是每一个订阅列表的地址,key是该订阅列表所相应的topic,其内容是从根节点到当前节点的topic内容所组成,以图5-3所看到的的hash表为例,节点c1相应的hash表项的key是:a1/b1/c1。value及时Lc1。针对图5-3中所看到的的订阅树,其产生的订阅hash表如图5-5所看到的:

8-3订阅hash表

8.3、 优化方法

订阅机制的优化主要集中在文件subs.c中。详细则涉及下面接口函数:

mqtt3_retain_queue

mqtt3_subs_clean_session

mqtt3_db_messages_queue

mqtt3_sub_remove

mqtt3_sub_add

在mqtt3_sub_add函数中主要完毕mosquitto的订阅操作,将首先搜索hash表中是否存在该context所订阅的topic。假设存在。则将其挂到相应的订阅列表中就可以,否则创建一个新的hash结构体,在该结构体中保存此topic。并将context挂到该topic的订阅列表中。

函数mqtt3_db_messages_queue中主要完毕mosquitto的消息公布操作。在该函数中将对topic进行拆分检查各种以“#”结尾的子topic是否存在于订阅hash表中,假设存在则进行消息发送。比如某一context欲向主题:a1/b1/c1公布消息,则须要在函数mqtt3_db_messages_queue中检查下面几种topic是否存在于订阅hash表中:

a1/#

a1/b1/#

a1/b1/c1/#

a1/b1/c1/

假设主题有存在于hash表中,则将消息挂载到相应topic订阅列表的各个context的消息队列中。

函数mqtt3_sub_remove和mqtt3_subs_clean_session主要完毕在hash表中清除context的操作,该操作须要事先保存context所订阅的topic。此时仅仅需查找其所订阅的topic是否存在于订阅hash表中就可以,假设存在,则再从订阅列表中删除该context,否则直接返回。

函数mqtt3_retain_queue完毕对某个context的消息队列的保存操作,它相同不须要遍历订阅树。仅仅须要依据其操作的context中取出所订阅的topic。然后再通过该topic从订阅hash表中找到相应的context就可以调用_retain_process函数直接完毕操作。

优化后的mosquitto程序不支持通配符“+”,可是支持通配符“#”。

Mosquito的优化——订阅树优化(八)的更多相关文章

  1. [USACO2005][POJ3171]Cleaning Shifts(DP+线段树优化)

    题目:http://poj.org/problem?id=3171 题意:给你n个区间[a,b],每个区间都有一个费用c,要你用最小的费用覆盖区间[M,E] 分析:经典的区间覆盖问题,百度可以搜到这个 ...

  2. Weak Pair---hud5877大连网选(线段树优化+dfs)

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5877  题意:给你一颗树,有n个节点,每个节点都有一个权值v[i]:现在求有多少对(u,v ...

  3. CodeForces 558E(计数排序+线段树优化)

    题意:一个长度为n的字符串(只包含26个小字母)有q次操作 对于每次操作 给一个区间 和k k为1把该区间的字符不降序排序 k为0把该区间的字符不升序排序 求q次操作后所得字符串 思路: 该题数据规模 ...

  4. HDU4719-Oh My Holy FFF(DP线段树优化)

    Oh My Holy FFF Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) T ...

  5. 游戏AI(二)—行为树优化之

    上一篇我们讲到了AI架构之一的行为树,本篇文章和下一篇文章我们将对行为树进行优化,在本篇文章中我们讲到的是内存优化 问题 上一篇中我们设计的行为树由于直接采用new进行动态内存分配,没有自己进行管理. ...

  6. UOJ#77. A+B Problem [可持久化线段树优化建边 最小割]

    UOJ#77. A+B Problem 题意:自己看 接触过线段树优化建图后思路不难想,细节要处理好 乱建图无果后想到最小割 白色和黑色只能选一个,割掉一个就行了 之前选白色必须额外割掉一个p[i], ...

  7. Codeforces 558E A Simple Task (计数排序&&线段树优化)

    题目链接:http://codeforces.com/contest/558/problem/E E. A Simple Task time limit per test5 seconds memor ...

  8. 2019.03.09 codeforces833B. The Bakery(线段树优化dp)

    传送门 线段树优化dpdpdp入门题. 要求把nnn个数分成kkk段,每段价值为里面不相同的数的个数,求所有段的价值之和最大值.n≤35000,k≤50n\le35000,k\le50n≤35000, ...

  9. Codeforces 1045. A. Last chance(网络流 + 线段树优化建边)

    题意 给你 \(n\) 个武器,\(m\) 个敌人,问你最多消灭多少个敌人,并输出方案. 总共有三种武器. SQL 火箭 - 能消灭给你集合中的一个敌人 \(\sum |S| \le 100000\) ...

随机推荐

  1. React Native入门——IDE及其它相关基础技术

    关于React Native的开发,当中一个问题是缺少好用的IDE,有些人说不就是JS么,搞一个记事本也就写了,那样尽管牛逼,但事实上还是非常头大的,有一款好的IDE还是能提升开发效率的,这里对几个还 ...

  2. JAVA File类 分析(二)

    本章開始介绍UNIX文件系统. 文件系统是怎样管理文件的呢?那咱们要先文件的存储介质開始--磁盘 磁盘是计算机系统的一个硬件设备,文件系统为了可以管理磁盘.对其进行了三层抽象(本文全部内容均指UNIX ...

  3. 漫漫人生路-学点Jakarta基础-Java8新特性 Stream/Lambda

    背景 Stream 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利.高效的聚合操作(aggregate operation),或者大批量数据操作 (bulk dat ...

  4. single-page关于vue-router

    最近复习了vue,项目实战前有练手,做一个简单的单页面应用. 1.router-view就是我们渲染的组件,router-view被包裹在一个div中,一旦路由跳转,router-view就会被渲染为 ...

  5. 关于 js 的框架方向

    关于 js 的框架方向 http://www.breck-mckye.com/blog/2014/12/the-state-of-javascript-in-2015/?utm_source=ourj ...

  6. 分享js寄生组合模式继承

    function person(){ this.name = 'taobao'; this.showMess = function(){ return this.name; } } person.pr ...

  7. at&&atq&&atrm---定时任务

    at放在 ls /var/spool/at/ 目录下 At的配置文件/etc/at.deny和/etc/at.allow 如果deny单独存在,则是deny以为的所有用户都可以使用at命令 如果all ...

  8. 【Codeforces Round #427 (Div. 2) A】Key races

    [Link]:http://codeforces.com/contest/835/problem/A [Description] [Solution] 傻逼题. [NumberOf WA] [Revi ...

  9. 各种join一目了然: join 、inner join、left join 、right join、full join

    各种join一幅图一目了然 一下每幅图都是指: A * join B on A.id = B.in 这个帖子也非常形象.比較好:http://www.phpddt.com/db/inner_join- ...

  10. Delphi(Tuxedo,BDE,ADO)三合一数据集组件HsTxQuery

    Delphi(Tuxedo,BDE,ADO)三合一数据集组件HsTxQuery 一.背景 为什么要做这个三合一数据集组件呢?曾经我们公司用delphi开发的系统大多以ADO,BDE方式来连接数据库,这 ...