vpp hash源码分析

news2024/11/27 5:32:19
  • 概述

vpp的hash结构分为hash头、桶(_hash_create或hash_resize申请)和桶下元素(clib_mem_realloc申请),总共3个部分组成。

根据元素key的hash值不同,分配到不同的桶下,与其他hash表原理相同。

vpp的hash结构默认是支持动态扩容的,即当hash表存放键值对大于3/4哈希桶的个数时,会2倍扩容。

哈希冲突时,vector长度认为是没有限制的。

如非特殊说明,以存储key和value来进行介绍,即log2_pair_size > 0。

(免费订阅,永久学习)学习地址: Dpdk/网络协议栈/vpp/OvS/DDos/NFV/虚拟化/高性能专家-学习视频教程-腾讯课堂

更多DPDK相关学习资料有需要的可以自行报名学习,免费订阅,永久学习,或点击这里加qun免费
领取,关注我持续更新哦! ! 

 

  • hash结构图

hash struct (原图更清晰)

  1. hash_t:hash_header
/* Vector header for hash tables. */
typedef struct hash_header
{
  /* 哈希表元素数量,包括所有桶下的元素 */
  uword elts;

  /* 标记位,包括以下3种取值 */
  u32 flags;

  /* 自动扩容,默认打开 */
#define HASH_FLAG_NO_AUTO_GROW		(1 << 0)
  /* 自动缩减,默认关闭 */
#define HASH_FLAG_NO_AUTO_SHRINK	(1 << 1)
  /* 当hash_next在遍历此散列表的过程中进行时设置 */
#define HASH_FLAG_HASH_NEXT_IN_PROGRESS (1 << 2)

  /* 0:不存储key  >0:存储key+value大小的log2值 */
  u32 log2_pair_size;

  /* 哈希函数,包括以下5种取值 */
  hash_key_sum_function_t *key_sum;

  /* Special values for key_sum "function". */
#define KEY_FUNC_NONE		(0)	/*< sum = key */
#define KEY_FUNC_POINTER_UWORD	(1)	/*< sum = *(uword *) key */
#define KEY_FUNC_POINTER_U32	(2)	/*< sum = *(u32 *) key */
#define KEY_FUNC_STRING         (3)	/*< sum = string_key_sum, etc. */
#define KEY_FUNC_MEM		(4)	/*< sum = mem_key_sum */

  /* 比较函数 */
  hash_key_equal_function_t *key_equal;

  /* 用户自定义数据 */
  any user;

  /* Format函数 */
  format_function_t *format_pair;

  /* Format函数参数 */
  void *format_pair_arg;

  /* 1:有一个元素   0:无元素或有冲突元素 */
  uword is_user[0];
} hash_t;

2. hash结构内存分布:

hash表的handler是hash_t指针,经过初始化、插入元素后,内存结构如上图所示。

(1)红色部分(hash结构)是一块连续内存,在_hash_create后形成

(2)每个桶下的元素,是在lookup--->set_indirect--->clib_mem_realloc中申请的(2个及以上元素时)

3. 存储key和value:

(1)log2_pair_size=0时,不存储value,hash_pair_indirect_t中的pairs是vec结构,上图黄色所示

(2)log2_pair_size>0时,存储value,value_len = 2^log2_pair_size - 1

(3)key的大小是uword的,在x64系统是8字节。如果key超过8字节,只能存储指针,创建时使用hash_create_mem函数,key会被保存,但无法访问,是hash表的私有内存。mhash可以存储key,hash常常与pool配合使用

4. hash无冲突:

使用hash_pair_t记录key和value。如果is_user[i]为0,没有元素;为1,则表示有1个元素

5. hash冲突:

使用hash_pair_indirect_t记录key和value,且is_user[i]为0。

在_hash_create时,桶创建的结构体是hash_pair_t。在冲突时,将hash_pair_t*转成hash_pair_union_t*,使用其中的hash_pair_indirect_t*指针,获取hash_pair_indirect_t中内容。如果不理解此段,可看下面的示例

仔细分析lookup(SET)---> set_indirect_is_user流程:当前桶下1个元素扩充到2个元素的过程。

(1)首先,调用key_sum函数,获取桶的index

(2)通过get_pair拿到桶下唯一元素,此时 hash_pair_t *强转成hash_pair_union_t *,实际内容是 hash_pair_t

(3)hash_is_user函数的返回值是1,因为只有一个元素,准备SET第二个元素

(4)found_key当然是没找到了,准备加入新元素,否则,覆盖之后还是一个元素

(5)调用set_indirect_is_user函数,hash_pair_indirect_t *pi = &p->indirect,在(2)中,p是hash_pair_t *强转成hash_pair_union_t *的,p只有hash_pair_t内容。pi的第一个元素是hash_pair_t *pairs,那么pi->pairs的地址与之前p->direct的地址是一致的,这样就把最初的hash_pair_t*转换成了hash_pair_indirect_t的pairs了。用clib_memcpy_fast将第一个元素拷贝到新申请的内存中,然后将pi->pairs指向新申请的内存,更新长度、位图等标记位,最终返回新元素,即第二个元素

  • 主要函数

1. hash_create:

有7种hash创建函数,hash_create_mem(key是指针)、hash_create_vec(key是vec数组)、hash_create_shmem(同mem)、hash_create_string(key是string)、hash_create、hash_create_uword(key是8字节指针)、hash_create_u32(key是4字节指针)。

所有函数最终会调用 hash_create2函数,初始化format、hash等参数,然后调用_hash_create函数,申请所有桶,再初始化剩余参数,elts、log2_pair_size等。

hash表使用前只需要调用 hash_create_*** 一个函数即可。

hash create后内存结构

2. hash_set:

hash_set最终会调用 lookup函数,op参数是SET。

(1)key_sum:获取桶的index,hash_create_***确定使用哪种hash 函数来计算

(2)get_pair:通过index,找到对应桶

(3)hash_is_user:判断当前桶是否有元素,是否冲突。取值是1(无冲突),桶中有1个元素,调用set_indirect_is_user函数,再添加一个,变成2个,上面已进行过分析;取值是0,分两种情况:

【1】空桶,直接赋值,调用set_is_user函数设置位图

【2】冲突,set_indirect函数处理冲突,即元素挂在桶的末尾

hash桶中1个元素或多个元素内存结构

3. hash_unset:

hash_unset最终会调用 lookup函数,op参数是UNSET。

(1)key_sum函数获取桶的index,get_pair函数找到对应桶

(2)如果桶下只有一个元素(hash_is_user返回值是1),set_is_user设置位图,标记为无元素,zero_pair将元素清空;如果桶下有多个元素或无元素(hash_is_user返回值是0),get_indirect函数逐个key对比,找到对应元素或未找到元素,找到情况下,unset_indirect进行unset设置

(3)unset_indirect:找到末尾元素e,桶下元素长度len,分别处理len <=2 和 len > 2两种情况。len <=2时,分为=2和=1两种情况,=2时判断删除的是桶下第一个还是第二个元素;=1时,直接删除这个元素即可。 len > 2时,拷贝末尾元素到待删除元素位置,然后更新len,如下图所示

unset_indirect函数 len &amp;amp;amp;amp;amp;amp;gt; 2 情况

(4)更新elts等变量

4. hash_get:

hash_get最终会调用 lookup函数,op参数是GET。

key_sum函数获取桶的index,get_pair函数找到对应桶,通过key_equal或get_indirect函数找到对应的元素,返回;未找到,则返回空。

5. hash_free:

通过vec_free或clib_mem_free函数释放每个桶下的元素,最后释放桶和所有vec内存。

6. hash_foreach_pair:

循环每个桶下的每个元素,调用body动作,与 hash_free 循环流程相似。

  • 函数调用

以ipiptunne_key_t 为例,介绍接口使用情况。

ipip_main_t *gm = &ipip_main;
/* 创建 */
gm->tunnel_by_key =
    hash_create_mem (0, sizeof (ipip_tunnel_key_t), sizeof (uword));

/* 添加 */
hash_set_mem_alloc (&gm->tunnel_by_key, key, t->dev_instance);

/* 删除 */
hash_unset_mem_free (&gm->tunnel_by_key, key);

/* 查询 */
uword *p = hash_get_mem (gm->tunnel_by_key, key);

原文链接:https://zhuanlan.zhihu.com/p/390870663  原文作者: 大白鲨

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/92231.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python利用pandas处理Excel数据的应用

最近迷上了高效处理数据的pandas&#xff0c;其实这个是用来做数据分析的&#xff0c;如果你是做大数据分析和测试的&#xff0c;那么这个是非常的有用的&#xff01;&#xff01;但是其实我们平时在做自动化测试的时候&#xff0c;如果涉及到数据的读取和存储&#xff0c;那么…

二叉树5:二叉树层序遍历

学会二叉树的层序遍历&#xff0c;可以一口气打完以下十题&#xff1a; 强烈建议大家和我一样&#xff0c;先看一下第一道题&#xff0c;大家可以去看看卡哥的哔站视频&#xff0c;理解透。然后后面的九道题自己先动手做一下&#xff0c;别急着看答案&#xff0c;真心不难&…

Git流程规范

开发新功能 1、从master拉一个功能分支&#xff0c;取名为某个版本下的某个产品功能 4.3/精确发券 2、当功能开发好了&#xff0c;合并分支到dev进行联调 3、如果是俩个关联性的分支&#xff0c;应该把分支合并到另外一个分支&#xff0c;在合并到dev分支中。如图。feature3…

【学习笔记01】vue的了解和指令

一、什么是 Vue&#xff1f; Vue (发音为 /vjuː/&#xff0c;类似 view) 是一款用于构建用户界面的JavaScript框架。它基于标准 HTML、CSS 和 JavaScript 构建&#xff0c;并提供了一套声明式的、组件化的编程模型&#xff0c;帮助你高效地开发用户界面。 二、Vue的两个核心功…

Day831.局部变量为什么是线程安全的 -Java 并发编程实战

局部变量为什么是线程安全的 Hi&#xff0c;我是阿昌&#xff0c;今天学习记录的是关于局部变量为什么是线程安全的。 一遍一遍重复再重复地讲到&#xff0c;多个线程同时访问共享变量的时候&#xff0c;会导致并发问题。 那在 Java 语言里&#xff0c;是不是所有变量都是共…

【java设计】:全民飞机大战小游戏制作

文章目录 前言 一、全民飞机大战 二、计划安排 三、源码图和类图展示

CTF Android逆向 -- KGB Messenger APK文件结构介绍,破解账户与密码,静态分析,修改并构建APK,逆向算法,APK文件签名

前言 一次练习Android逆向的记录&#xff0c;写得很详细&#xff0c;有什么没有理解的地方可以私信 csdn不让我加外链&#xff0c;所以将链接前面的#号去掉即可 题目&#xff1a; ht#tps://github.com/tlamb96/kgb_messenger在这个挑战中&#xff0c;一共有三个flag&#x…

UE4 Pak打包、挂载、加载

首先&#xff0c;必须得明确的一点就是如果想要加载Pak内资源&#xff0c;那么这些资源必须是经过Cook的。如果打包的是未Cook的资源&#xff0c;那么即使Pak挂载成功&#xff0c;也不可能会成功加载Pak内资源。 不知道怎么生成Cook资源&#xff0c;可以看我前一篇 ​​​​​…

持之以恒,方得始终|海联捷讯的六年数字化历程

企业数字化已经成为了企业家与管理者的共识。如何实现数字化转型&#xff0c;从认知到战略&#xff0c;上至组织文化&#xff0c;下至每个组织成员的行为&#xff0c;都需要做出改变——它本质上是一种创新的企业管理模式和运营机制&#xff0c;重要性不言而喻。而降本增效也是…

学习->C++篇十七:C++的类型转换和IO流

目录 一.类型转换 1.C语言中的类型转换 2.C中的类型转换 二.IO流 1. C语言的输入与输出 2. 流是什么 3. stringstream 一.类型转换 1.C语言中的类型转换 &#xff08;1&#xff09;隐式类型转换&#xff0c;编译阶段自动进行&#xff0c;不能转换就编译报错。&#xff…

TCP/IP四层协议

七层模型层数太多记不住&#xff0c;四层模型 应用层&#xff0c;传输层&#xff0c;网络层&#xff0c;网络接口层的名字必须记得滚瓜烂熟。&#xff08;重点也是tcp/ip四层模型&#xff09; 四层模型&#xff1a; 1.应用层&#xff1a; 两台终端设备上的应用程序 应该遵守…

三面美团 Java 岗,HR 现场直接发 offer,他是横着走出来的

前情提要 这是一个发生在我朋友身上的真实事情&#xff1a; 这里就叫他程序员 Y 吧。 程序员 Y 工作不到两年&#xff0c;周末在朋友圈发了个喜报&#xff0c;准备入职美团。 之后&#xff0c;我就带着祝福跟 Y 聊了许久&#xff0c;聊天的内容就是具体了解一下他面试的过程…

技术分享之IntelliJ plugin

资料 https://zhaojian.blog.csdn.net/article/details/127882946 Plugin Configuration File https://plugins.jetbrains.com/docs/intellij/plugin-configuration-file.html 今天分享的主要内容: 了解插件能够做什么 如何开发一个插件 阅读两个常用的插件源码 intellij的窗…

15.Django大型电商项目之创建模型与sql表反向生成模型

1.用户模块模型类创建 1.1 创建用户的子应用 python .\manage.py startapp userapp在settings中挂载子应用 创建子应用urls.py 在主应用中加入子应用的urls.py 1.2 创建表 如何在直接导入sql文件形成表&#xff0c;这里就直接在navicate中把sql文件拖进去点击开始即可 这里…

大数据技术系列:图解大数据平台开发

导言 在前面的文章《「大数据技术体系」学习实践导览》中&#xff0c;概要式的梳理了大数据平台的业务目标&#xff0c;大数据平台的架构框架&#xff0c;大数据平台中常用的技术及工具&#xff0c;数据治理四方面的内容&#xff0c;算是对自身所了解大数据知识体系的抛砖引玉…

第十四届蓝桥杯集训——JavaC组第十二篇——while循环(循环四要素)

第十四届蓝桥杯集训——JavaC组第十二篇——while循环(循环四要素) 前言 百度解析&#xff1a;以环形、回路或轨道运行;沿曲折的路线运行;特指运行一周而回到原处,再转。或说反复地连续做某事。 那么&#xff0c;在程序中依然是连续重复的按照一定的规则去执行某事。 程序计数器…

如何把视频分屏?教你轻松学会视频分屏

分屏视频该怎么操作&#xff1f;不知道大家有没有看到过这样一个视频&#xff0c;就是一个视频里有两个或者有更多个画面&#xff0c;我们在观看的时候可以同时看好几个画面。其实这就是分屏视频&#xff0c;在一个页面中加入多个画面。这样的视频是不是既好玩又炫酷呢&#xf…

尚硅谷Promise笔记

文章目录一、Promise介绍与基本使用1-1.初体验之promise封装ajax请求1-2.Promise对象状态属性PromiseState的值有三个1-3.Promise对象状态属性PromiseResults二、Promise API2-1.Promise构造函数Promise(excutor){}2-2.Promise.prototype.then 方式&#xff1a;(onResolved,onR…

App 黑白化技术实践

前言 很高兴遇见你~ 最近打开各大 App 会发现它们都做了黑白化&#xff0c;如下支付宝的处理&#xff1a; 可以看到应用设置了全局灰色调&#xff0c;表达了一种对逝者的哀悼&#xff0c;非常的应景和人性化。作为程序猿&#xff0c;我们来探索一下它从技术角度是怎么实现的。…

[附源码]Python计算机毕业设计SSM基于java旅游信息分享网站(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…