Mosquitto-1.5.4源码分析,主题订阅的数据结构及SUBSCRIBE的函数跳转关系

简介: Mosquitto-1.5.4源码分析,主题订阅的数据结构及SUBSCRIBE的函数跳转关系

1.4.x之前的版本可以参考博客,使用的是树来实现:



mosquito从版本1.5.x开始,主题订阅的数据结构有变化。采用哈希表来存储。每一层都有一个哈希表来存储。


/src/database.c


这里初始化了两个主题,一个是业务主题“”,为空;另一个是系统主题“$SYS”


函数sub__add_hier_entry很重要,新增哈希key-value都靠它来实现。


int db__open(struct mosquitto__config *config, struct mosquitto_db *db)
{
  struct mosquitto__subhier *subhier;
  if(!config || !db) return MOSQ_ERR_INVAL;
  db->last_db_id = 0;
  db->contexts_by_id = NULL;
  db->contexts_by_sock = NULL;
  db->contexts_for_free = NULL;
#ifdef WITH_BRIDGE
  db->bridges = NULL;
  db->bridge_count = 0;
#endif
  // Initialize the hashtable
  db->clientid_index_hash = NULL;
  db->subs = NULL;
    subhier = sub__add_hier_entry(NULL, &db->subs, "", strlen(""));//业务子树根节点
  if(!subhier) return MOSQ_ERR_NOMEM;
    subhier = sub__add_hier_entry(NULL, &db->subs, "$SYS", strlen("$SYS"));//系统子树根节点
  if(!subhier) return MOSQ_ERR_NOMEM;
subs.c,会创建内存
child = mosquitto__malloc(sizeof(struct mosquitto__subhier));
struct mosquitto__subhier *sub__add_hier_entry(struct mosquitto__subhier *parent, struct mosquitto__subhier **sibling, const char *topic, size_t len)
{
  struct mosquitto__subhier *child;
  assert(sibling);
  child = mosquitto__malloc(sizeof(struct mosquitto__subhier));
  if(!child){
  log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory.");
  return NULL;
  }
  child->parent = parent;
  child->topic_len = len;
  if(UHPA_ALLOC_TOPIC(child) == 0){
  child->topic_len = 0;
  mosquitto__free(child);
  log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory.");
  return NULL;
  }else{
  strncpy(UHPA_ACCESS_TOPIC(child), topic, child->topic_len+1);
  }
  child->subs = NULL;
  child->children = NULL;
  child->retained = NULL;
  if(child->topic_len+1 > sizeof(child->topic.array)){
  if(child->topic.ptr){
    HASH_ADD_KEYPTR(hh, *sibling, child->topic.ptr, child->topic_len, child);
  }else{
    mosquitto__free(child);
    return NULL;
  }
  }else{
  HASH_ADD(hh, *sibling, topic.array, child->topic_len, child);
  }
  return child;
}


image.png

截图1



每一层都有一个哈希表来存储。


例如,系统消息的主题表示为:


$SYS/broker/version


$SYS/broker/uptime


$SYS/broker/clients/total


$SYS/broker/clients/inactive


$SYS/broker/clients/disconnected


哈希表结构我用草图绘制,如截图2所示


image.png


截图2


subs.c源文件的static int sub__add_recurse()函数是核心所在,负责添加哈希元素。


对于业务主题(非系统主题)的订阅,其流程如下,请观看截图3的下半部分,有详细的函数跳转流程:

image.png


image.png

截图3


订阅的最终目标就是执行语句HASH_ADD(hh, *sibling, topic.array, child->topic_len, child); 往哈希表添加元素!


相关文章
|
25天前
|
存储 人工智能 算法
数据结构实验之C 语言的函数数组指针结构体知识
本实验旨在复习C语言中的函数、数组、指针、结构体与共用体等核心概念,并通过具体编程任务加深理解。任务包括输出100以内所有素数、逆序排列一维数组、查找二维数组中的鞍点、利用指针输出二维数组元素,以及使用结构体和共用体处理教师与学生信息。每个任务不仅强化了基本语法的应用,还涉及到了算法逻辑的设计与优化。实验结果显示,学生能够有效掌握并运用这些知识完成指定任务。
44 4
|
6月前
|
算法
数据结构和算法学习记录——线性表之双向链表(上)-结点类型定义、初始化函数、创建新结点函数、尾插函数、打印函数、尾删函数
数据结构和算法学习记录——线性表之双向链表(上)-结点类型定义、初始化函数、创建新结点函数、尾插函数、打印函数、尾删函数
52 0
|
6月前
|
存储 JavaScript 前端开发
JavaScript中的对象是数据结构,存储键值对,键为字符串,值可为任意类型,包括函数(作为方法)
【6月更文挑战第25天】JavaScript中的对象是数据结构,存储键值对,键为字符串,值可为任意类型,包括函数(作为方法)。
42 2
|
5月前
|
消息中间件 存储 NoSQL
Redis数据结构—跳跃表 skiplist 实现源码分析
Redis 是一个内存中的数据结构服务器,使用跳跃表(skiplist)来实现有序集合。跳跃表是一种概率型数据结构,支持平均 O(logN) 查找复杂度,它通过多层链表加速查找,同时保持有序性。节点高度随机生成,最大为 32 层,以平衡查找速度和空间效率。跳跃表在 Redis 中用于插入、删除和按范围查询元素,其内部节点包含对象、分值、后退指针和多个前向指针。Redis 源码中的 `t_zset.c` 文件包含了跳跃表的具体实现细节。
|
6月前
数据结构学习记录——判断是否为同一颗二叉搜索树(题意理解、求解思路、程序搭建框架、具体函数的实现)
数据结构学习记录——判断是否为同一颗二叉搜索树(题意理解、求解思路、程序搭建框架、具体函数的实现)
62 2
|
7月前
【数据结构】二叉树-堆(函数实现)
【数据结构】二叉树-堆(函数实现)
27 2
|
6月前
|
存储 算法
数据结构学习记录——集合及运算(集合的表示、并查集、树结构表示集合、集合运算、查找函数、并运算)
数据结构学习记录——集合及运算(集合的表示、并查集、树结构表示集合、集合运算、查找函数、并运算)
37 0
|
6月前
|
算法
数据结构和算法学习记录——初识二叉树(定义、五种基本形态、几种特殊的二叉树、二叉树的重要性质、初识基本操作函数)
数据结构和算法学习记录——初识二叉树(定义、五种基本形态、几种特殊的二叉树、二叉树的重要性质、初识基本操作函数)
61 0
|
6月前
|
存储 算法
数据结构和算法学习记录——特殊线性表之队列-队列的概念、队列结构体类型定义 、基本接口函数、初始化函数、销毁队列函数、入队列函数、判断队列是否为空、出队列函数、读取队头队尾的数据 、计算队列数据个数
数据结构和算法学习记录——特殊线性表之队列-队列的概念、队列结构体类型定义 、基本接口函数、初始化函数、销毁队列函数、入队列函数、判断队列是否为空、出队列函数、读取队头队尾的数据 、计算队列数据个数
43 0
|
6月前
|
算法 C语言
数据结构和算法学习记录——特殊线性表之栈(下)-销毁栈函数、判断栈是否为空、压栈函数、出栈函数、取栈顶元素、计算栈中有多少个元素、栈有关习题-有效的括号
数据结构和算法学习记录——特殊线性表之栈(下)-销毁栈函数、判断栈是否为空、压栈函数、出栈函数、取栈顶元素、计算栈中有多少个元素、栈有关习题-有效的括号
38 0

热门文章

最新文章