DPDK-Hash(2)

简介: DPDK-Hash(2)

前言


第一章节介绍了DPDK的相关原理,和DPDK采用Cuckoo hash 相关性能指标。本章节主要是介绍DPDK hash 常用的 api 接口。


一、DPDK Hash


DPDK Hash Libary 提供函数主要是实现增加(add),删除(del), 查找(lookup),遍历(iterate)等功能。


二、DPDK hash 常用的API接口


1.DPDK 结构体

创建Hash 使用的参数结构体 如下:

/**
 * Parameters used when creating the hash table.
 */
struct rte_hash_parameters {
  const char *name;   /**< Name of the hash. */   //此名字具备唯一性, 在dpdk 中hash ,ring 等都需要唯一性名字
  uint32_t entries;   /**< Total hash table entries. */     // 创建的Hash 表容量,支持多少个条目
  uint32_t reserved;    /**< Unused field. Should be set to 0 */ // 保留
  uint32_t key_len;   /**< Length of hash key.*/ //每个Hash key 的长度。Hash 表中的Hash key 长度是统一的,有此处设置大小。
  rte_hash_function hash_func;  /**< Primary Hash function used to calculate hash. */ cuckoo Hask 需要两个Hash function,在这里设置Cuckoo Hash的主计算Function
  uint32_t hash_func_init_val;  /**< Init value used by hash_func. */
  int socket_id;      /**< NUMA Socket ID for memory. */ 此处表示Hash创建在那个物理socket_id 上。
  uint8_t extra_flag;   /**< Indicate if additional parameters are present. */
};

2. DPDK 常用接口

DPDK Hash API常用接口如下:

DPDK Hash API 大部分在<rte_hash.h> 中
// Hash table 的创建函数
struct rte_hash *rte_hash_create(const struct rte_hash_parameters *params);
// Hash add API 提供了四种
// hash_header + key
int32_t rte_hash_add_key(const struct rte_hash *h, const void *key);
// Hash_header + key + data. 在对应的Hash 表中存储数据data.
int rte_hash_add_key_data(const struct rte_hash *h, const void *key, void *data);
// Hash_headr +key + hask_function(slaver function)
int32_t rte_hash_add_key_with_hash(const struct rte_hash *h, const void *key, hash_sig_t sig);
// Hash_hader+key+
int32_t rte_hash_add_key_with_hash_data(const struct rte_hash *h, const void *key,hash_sig_t sig, void *data);
// 删除
// 根据key 删除 
int32_t rte_hash_del_key(const struct rte_hash *h, const void *key);
// 根据key和slave Hash function vale 
int32_t rte_hash_del_key_with_hash(const struct rte_hash *h, const void *key, hash_sig_t sig);
// 重置真个hash table
void rte_hash_reset(struct rte_hash *h);
// 遍历整个表
int32_t rte_hash_iterate(const struct rte_hash *h, const void **key, void **data, uint32_t *next);

三、DPDK 提供的Hash 算法


DPDK hash 提供了默认的默认的Hash 计算primary function. 如果不设置h->hash_func 就使用初始化默认的hash 函数


Hash 计算的slave function 可以使用rte_hash_hash(const struct rte_hash *h, const void *key) 获取。

Hash 计算函数可以自己定义: 比如l3fwd中。哈希函数就是自定义的。


四、DPDK Hash Demo


#include <stdio.h>
#include <arpa/inet.h>
#include <rte_eal.h>
#include <rte_ethdev.h>
//#include <rte_log.h>
#include <rte_hash.h>
#include <rte_jhash.h>
// hash表,也就是实现增删改查等功能
#define HASH_ENTRI_MAXNUM 1<<12
#define HUSH_KEY_COUNT   1<< 4
// 创建Hash key。 此处采用TUPLE5
struct net_key {
  uint32_t sip;
  uint32_t dip;
  uint16_t sport;
  uint16_t dport;
  char proto;
};
static void print_key (struct net_key *key) {
  printf("sip: %x dip: %x sport: %x dport %x proto:%d \n", 
    key->sip, key->dip, key->sport, key->dport, key->proto);  
}
// DPDK 创建表,队列等都需要自定义名字
static struct rte_hash * create_hash_table(const char *name){
  struct rte_hash_parameters *param = (struct rte_hash_parameters *) malloc(sizeof(struct rte_hash_parameters));
  if (!param) return NULL;
  param->name = name;
  param->entries = HASH_ENTRI_MAXNUM;
  param->key_len = sizeof(struct net_key);
  param->hash_func = rte_jhash; //  hash 函数
  param->hash_func_init_val = 0;
  param->socket_id =rte_socket_id();               // 进行NUMA, 这个是表示每一块内存上的寻址。
  struct rte_hash *hash = rte_hash_create(param);
  if (hash == NULL) {
    //RTE_LOG(INFO, Hash, "========================\n");    
  }
  return hash;
}
//DPDK 添加方式有四种
int main(int argc, char *argv[]){
  // DPDK 环境初始化
  rte_eal_init(argc, argv);
  int i = 0;
  uint32_t  net_sip;
  uint32_t  net_dip;
  uint16_t  sport;
  uint16_t  dport;
  inet_pton(AF_INET,"192.168.1.1",&net_sip);
  inet_pton(AF_INET,"192.168.2.1", &net_dip);
  sport = htons(5000);
  dport = htons(6000);
  struct rte_hash *hash  = create_hash_table("cuckoo hash table");
  for (i = 0; i < HUSH_KEY_COUNT; i++){
    struct net_key *nk = malloc(sizeof(struct net_key));
    nk->sip = net_sip + i;
    nk->dip = net_dip + i;
    nk->sport = sport+ i;
    nk->dport = dport + i;
    nk->proto = i % 2;
    // key 
    // key hash
    // key data+
    // key hash, data
    if(i % 4 == 0) {
      //rte_hash_add_key(hash, nk);
    }else if(i % 4 == 1){ // 第二种添加
      hash_sig_t key2 = rte_hash_hash(hash, nk);
      rte_hash_add_key_with_hash(hash, nk, key2);
    }
    else if (i %4 == 2){ // 第三种添加
      uint32_t* tmpdata = (uint32_t *)malloc(sizeof(uint32_t));
      *tmpdata = i;
      rte_hash_add_key_data(hash, nk, (void *)tmpdata);
    }else {
      hash_sig_t key4 = rte_hash_hash(hash, nk);
      uint32_t* tmp = (uint32_t *)malloc(sizeof(uint32_t));
      *tmp= i;
      rte_hash_add_key_with_hash_data(hash, nk, key4, (void *)tmp);
    }
  }
#if 0
  for (i = 0;i < HUSH_KEY_COUNT;i ++) {
    struct net_key *nk = malloc(sizeof(struct net_key));
    nk->sip = net_sip + i;
    nk->dip = net_dip + i;
    nk->sport = sport+ i;
    nk->dport = dport + i;
    nk->proto = i % 2;
    int idx = rte_hash_lookup(hash, nk);
    printf("hash lookup --> sip: %x, idx: %d\n", nk->sip, idx);
    rte_hash_del_key(hash, nk);
    free(nk);
  } 
#endif
  struct net_key *key = NULL;
  void *value = NULL;
  uint32_t next =0;
  while (rte_hash_iterate( hash, (const void **)&key, &value,&next) >= 0){
    print_key(key);
    if (value != NULL)
      printf("value : %u \n", *(uint32_t*)value);
  }
  return 0;
}


结果 :


总结


提示:这里对文章进行总结:

目录
相关文章
|
6月前
|
存储 数据挖掘 API
DPDK_Hash(1)
DPDK_Hash(1)
188 0
|
4月前
|
算法
Ngnix02 --- Ngnix的功能特性及常见功能,Ngnix常用的功能模块,有不同算法,根据不同算法进行转发,ip_hash、url_hash、fair,核心组成 ngnix二进制可执行文件
Ngnix02 --- Ngnix的功能特性及常见功能,Ngnix常用的功能模块,有不同算法,根据不同算法进行转发,ip_hash、url_hash、fair,核心组成 ngnix二进制可执行文件
|
6月前
|
存储 前端开发 JavaScript
hash 的特性与运用
hash 的特性与运用
|
6月前
|
Ubuntu
[DPDK] dpdk测试收包
[DPDK] dpdk测试收包
|
存储 算法 安全
Hash 算法详细介绍与实现 (二)
书接上回,昨天写了第一部分,《Hash 算法详细介绍与实现 (一)》详细介绍了Hash表和Hash算法的相关概念以及算法的基本原理。同时简单介绍几种hash算法的实现:直接取余法和乘法取整法;本文接着详细唠唠Hash算法和Hash表这个数据结构的具体实现以及Hash算法和Hash表常见问题的解决方案,比如解决Hash表的冲突问题等等.相关的理论知识已在上篇文章详细介绍,这里就不再赘述,多的不说少的不唠,直接进入今天的主题:利用Hash算法实现Hash表
480 1
|
NoSQL Redis
Redis集群环境各节点无法互相发现与Hash槽分配异常 CLUSTERDOWN Hash slot not served的解决方式
Redis集群环境各节点无法互相发现与Hash槽分配异常 CLUSTERDOWN Hash slot not served的解决方式
253 0
|
存储 安全 调度
DPDK环形缓冲区(Ring)详解及性能优化
DPDK环形缓冲区(Ring)详解及性能优化
|
存储 算法 Java
Hash 冲突 | 学习笔记
快速学习 Hash 冲突。
|
人工智能 程序员 开发者
《深入浅出DPDK》—第2章2.5节Cache预取
以上章节讲到了多种和Cache相关的技术,但是事实上,Cache对于绝大多数程序员来说都是透明不可见的。程序员在编写程序时不需要关心是否有Cache的存在,有几级Cache,每级Cache的大小是多少;不需要关心Cache采取何种策略将指令和数据从内存中加载到Cache中;也不需要关心Cache何时将处理完毕的数据写回到内存中。
4720 0
|
存储 算法 安全
什么是 Hash 算法?
散列算法(Hash Algorithm),又称哈希算法,杂凑算法,是一种从任意文件中创造小的数字「指纹」的方法。与指纹一样,散列算法就是一种以较短的信息来保证文件唯一性的标志,这种标志与文件的每一个字节都相关,而且难以找到逆向规律。因此,当原有文件发生改变时,其标志值也会发生改变,从而告诉文件使用者当前的文件已经不是你所需求的文件。
什么是 Hash 算法?