以下是rte_hash_add_key_data函数的代码实现,可以看到在存储data时,是通过指向data变量的指针地址进行哈希计算和存储的。
int rte_hash_add_key_data(const struct rte_hash *h, const void *key,
void *data)
{
uint32_t bucket_idx, idx;
uint64_t sig = 0;
struct rte_hash_bucket *bkt;
struct rte_hash_key *k = NULL;
/* Calculate the hash signature */
sig = h->hash_func(key, h->key_len, h->hash_func_init_val);
/* Get bucket index from hash signature */
bucket_idx = sig & h->bucket_bitmask;
/* Look up an empty slot for this key in the bucket */
bkt = &h->buckets[bucket_idx];
idx = get_empty_slot(bkt);
if (idx == INVALID_SLOT) {
RTE_LOG(DEBUG, HASH, "Bucket %u full\n", bucket_idx);
return -ENOSPC; // No space left in the bucket
}
/* Add key and data to bucket */
#if defined(RTE_ARCH_X86) || defined(RTE_ARCH_ARM64)
/* Use special versions for certain architectures where comparison of two keys can be done in parallel with their processing. */
#define USE_OPTIMIZED_FUNC
#endif
#ifdef USE_OPTIMIZED_FUNC
#ifdef RTE_MACHINE_CPUFLAG_AVX512F
#define COMPARE_KEYS(x,y,z) \
_mm_cmpeq_epi8_mask(_mm_load_si128((const __m128i *)(x)), \
_mm_load_si128((const __m128i *)(y)))
#else
#define COMPARE_KEYS(x,y,z) \
compare_key(x, y, z)
#endif
#ifndef RTE_MACHINE_CPUFLAG_AVX512F
if (h->use_rte_hash_crc) {
/* Use CRC instructions for enhanced hash functions */
k = &bkt->key[idx];
rte_hash_crc_calc(key, h->key_len,
&k->sig);
} else
#endif
{
/* Use default hash function */
k = &bkt->key[idx];
k->sig = sig;
}
*(void **)(uintptr_t)&bkt->data[idx] = data;
#else /* USE_OPTIMIZED_FUNC */
#ifdef RTE_MACHINE_CPUFLAG_AVX512F
#define COMPARE_KEYS(x,y,z) \
_mm_cmpeq_epi8_mask(_mm_load_si128((const __m128i *)(x)), \
_mm_load_si128((const __m128i *)(y)))
#else
#define COMPARE_KEYS(x,y,z) \
compare_key(x, y, z)
#endif
#ifndef RTE_MACHINE_CPUFLAG_AVX512F
if (h->use_rte_hash_crc) {
/* Use CRC instructions for enhanced hash functions */
k = &bkt->key[idx];
rte_hash_crc_calc(key, h->key_len,
&k->sig);
} else
#endif
{
/* Use default hash function */
k = &bkt->key[idx];
k->sig = sig;
}
#ifdef RTE_ARCH_ARM64
memcpy(&bkt->__reserved[idx], data, sizeof(uintptr_t));
#else
bkt->__reserved[idx] = 0;
#endif
*(void **)&(bkt->__reserved[idx]) = data;
#endif /* USE_OPTIMIZED_FUNC */
return 0; // Success
}