static entry_locator ht_find(const census_ht *ht, census_ht_key key) { entry_locator loc = {0, 0, 0, NULL}; gpr_int32 idx = 0; ht_entry *ptr = NULL; GPR_ASSERT(ht != NULL); idx = find_bucket_idx(ht, key); ptr = ht->buckets[idx].next; if (ptr == NULL) { /* bucket is empty */ return loc; } if (keys_match(&ht->options, ptr, key)) { loc.bucket_idx = idx; loc.is_first_in_chain = 1; loc.found = 1; return loc; } else { for (; ptr->next != NULL; ptr = ptr->next) { if (keys_match(&ht->options, ptr->next, key)) { loc.bucket_idx = idx; loc.is_first_in_chain = 0; loc.found = 1; loc.prev_entry = ptr; return loc; } } } /* Could not find the key */ return loc; }
static inline struct tracing_map_elt * __tracing_map_insert(struct tracing_map *map, void *key, bool lookup_only) { u32 idx, key_hash, test_key; struct tracing_map_entry *entry; key_hash = jhash(key, map->key_size, 0); if (key_hash == 0) key_hash = 1; idx = key_hash >> (32 - (map->map_bits + 1)); while (1) { idx &= (map->map_size - 1); entry = TRACING_MAP_ENTRY(map->map, idx); test_key = entry->key; if (test_key && test_key == key_hash && entry->val && keys_match(key, entry->val->key, map->key_size)) { if (!lookup_only) atomic64_inc(&map->hits); return entry->val; } if (!test_key) { if (lookup_only) break; if (!cmpxchg(&entry->key, 0, key_hash)) { struct tracing_map_elt *elt; elt = get_free_elt(map); if (!elt) { atomic64_inc(&map->drops); entry->key = 0; break; } memcpy(elt->key, key, map->key_size); entry->val = elt; atomic64_inc(&map->hits); return entry->val; } } idx++; } return NULL; }