|
|
|
@ -107,75 +107,13 @@ typedef struct mdtab_shard { |
|
|
|
|
gpr_atm free_estimate; |
|
|
|
|
} mdtab_shard; |
|
|
|
|
|
|
|
|
|
/* hash seed: decided at initialization time */ |
|
|
|
|
static uint32_t g_hash_seed; |
|
|
|
|
static int g_forced_hash_seed = 0; |
|
|
|
|
|
|
|
|
|
/* linearly probed hash tables for static element lookup */ |
|
|
|
|
static grpc_mdelem *g_static_mdtab[GRPC_STATIC_MDELEM_COUNT * 2]; |
|
|
|
|
static size_t g_static_strtab_maxprobe; |
|
|
|
|
static size_t g_static_mdtab_maxprobe; |
|
|
|
|
|
|
|
|
|
static mdtab_shard g_shards[SHARD_COUNT]; |
|
|
|
|
|
|
|
|
|
static void gc_mdtab(grpc_exec_ctx *exec_ctx, mdtab_shard *shard); |
|
|
|
|
|
|
|
|
|
void grpc_test_only_set_metadata_hash_seed(uint32_t seed) { |
|
|
|
|
g_hash_seed = seed; |
|
|
|
|
g_forced_hash_seed = 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void grpc_mdctx_global_init(void) { |
|
|
|
|
size_t i; |
|
|
|
|
if (!g_forced_hash_seed) { |
|
|
|
|
g_hash_seed = (uint32_t)gpr_now(GPR_CLOCK_REALTIME).tv_nsec; |
|
|
|
|
} |
|
|
|
|
g_static_strtab_maxprobe = 0; |
|
|
|
|
g_static_mdtab_maxprobe = 0; |
|
|
|
|
#if 0 |
|
|
|
|
/* build static tables */ |
|
|
|
|
memset(g_static_mdtab, 0, sizeof(g_static_mdtab)); |
|
|
|
|
memset(g_static_strtab, 0, sizeof(g_static_strtab)); |
|
|
|
|
for (i = 0; i < GRPC_STATIC_MDSTR_COUNT; i++) { |
|
|
|
|
grpc_slice elem = &grpc_static_mdstr_table[i]; |
|
|
|
|
const char *str = grpc_static_metadata_strings[i]; |
|
|
|
|
uint32_t hash = gpr_murmur_hash3(str, strlen(str), g_hash_seed); |
|
|
|
|
*(grpc_slice *)&elem->slice = grpc_slice_from_static_string(str); |
|
|
|
|
*(uint32_t *)&elem->hash = hash; |
|
|
|
|
for (j = 0;; j++) { |
|
|
|
|
size_t idx = (hash + j) % GPR_ARRAY_SIZE(g_static_strtab); |
|
|
|
|
if (g_static_strtab[idx] == NULL) { |
|
|
|
|
g_static_strtab[idx] = &grpc_static_mdstr_table[i]; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (j > g_static_strtab_maxprobe) { |
|
|
|
|
g_static_strtab_maxprobe = j; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
for (i = 0; i < GRPC_STATIC_MDELEM_COUNT; i++) { |
|
|
|
|
grpc_mdelem *elem = &grpc_static_mdelem_table[i]; |
|
|
|
|
grpc_slice key = |
|
|
|
|
&grpc_static_mdstr_table[grpc_static_metadata_elem_indices[2 * i + 0]]; |
|
|
|
|
grpc_slice value = |
|
|
|
|
&grpc_static_mdstr_table[grpc_static_metadata_elem_indices[2 * i + 1]]; |
|
|
|
|
uint32_t hash = GRPC_MDSTR_KV_HASH(key->hash, value->hash); |
|
|
|
|
*(grpc_slice *)&elem->key = key; |
|
|
|
|
*(grpc_slice *)&elem->value = value; |
|
|
|
|
for (j = 0;; j++) { |
|
|
|
|
size_t idx = (hash + j) % GPR_ARRAY_SIZE(g_static_mdtab); |
|
|
|
|
if (g_static_mdtab[idx] == NULL) { |
|
|
|
|
g_static_mdtab[idx] = elem; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (j > g_static_mdtab_maxprobe) { |
|
|
|
|
g_static_mdtab_maxprobe = j; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
/* initialize shards */ |
|
|
|
|
for (i = 0; i < SHARD_COUNT; i++) { |
|
|
|
|
for (size_t i = 0; i < SHARD_COUNT; i++) { |
|
|
|
|
mdtab_shard *shard = &g_shards[i]; |
|
|
|
|
gpr_mu_init(&shard->mu); |
|
|
|
|
shard->count = 0; |
|
|
|
@ -187,8 +125,7 @@ void grpc_mdctx_global_init(void) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void grpc_mdctx_global_shutdown(grpc_exec_ctx *exec_ctx) { |
|
|
|
|
size_t i; |
|
|
|
|
for (i = 0; i < SHARD_COUNT; i++) { |
|
|
|
|
for (size_t i = 0; i < SHARD_COUNT; i++) { |
|
|
|
|
mdtab_shard *shard = &g_shards[i]; |
|
|
|
|
gpr_mu_destroy(&shard->mu); |
|
|
|
|
gc_mdtab(exec_ctx, shard); |
|
|
|
@ -298,30 +235,23 @@ static void rehash_mdtab(grpc_exec_ctx *exec_ctx, mdtab_shard *shard) { |
|
|
|
|
|
|
|
|
|
grpc_mdelem *grpc_mdelem_from_slices(grpc_exec_ctx *exec_ctx, grpc_slice key, |
|
|
|
|
grpc_slice value) { |
|
|
|
|
grpc_slice_static_intern(&key); |
|
|
|
|
grpc_slice_static_intern(&value); |
|
|
|
|
|
|
|
|
|
grpc_mdelem *static_elem = grpc_static_mdelem_for_static_strings( |
|
|
|
|
grpc_static_metadata_index(key), grpc_static_metadata_index(value)); |
|
|
|
|
if (static_elem != NULL) { |
|
|
|
|
return static_elem; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
uint32_t hash = |
|
|
|
|
GRPC_MDSTR_KV_HASH(grpc_slice_hash(key), grpc_slice_hash(value)); |
|
|
|
|
internal_metadata *md; |
|
|
|
|
mdtab_shard *shard = &g_shards[SHARD_IDX(hash)]; |
|
|
|
|
size_t i; |
|
|
|
|
size_t idx; |
|
|
|
|
|
|
|
|
|
GPR_TIMER_BEGIN("grpc_mdelem_from_metadata_strings", 0); |
|
|
|
|
|
|
|
|
|
if (grpc_is_static_metadata_string(key) && |
|
|
|
|
grpc_is_static_metadata_string(value)) { |
|
|
|
|
for (i = 0; i <= g_static_mdtab_maxprobe; i++) { |
|
|
|
|
grpc_mdelem *smd; |
|
|
|
|
idx = (hash + i) % GPR_ARRAY_SIZE(g_static_mdtab); |
|
|
|
|
smd = g_static_mdtab[idx]; |
|
|
|
|
if (smd == NULL) break; |
|
|
|
|
if (grpc_slice_cmp(key, smd->key) == 0 && |
|
|
|
|
grpc_slice_cmp(value, smd->value) == 0) { |
|
|
|
|
GPR_TIMER_END("grpc_mdelem_from_metadata_strings", 0); |
|
|
|
|
return smd; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
gpr_mu_lock(&shard->mu); |
|
|
|
|
|
|
|
|
|
idx = TABLE_IDX(hash, shard->capacity); |
|
|
|
|