static void sss_mc_add_rec_to_chain(struct sss_mc_ctx *mcc, struct sss_mc_rec *rec, uint32_t hash) { struct sss_mc_rec *cur; uint32_t slot; if (hash > MC_HT_ELEMS(mcc->ht_size)) { /* Invalid hash. This should never happen, but better * return than trying to access out of bounds memory */ return; } slot = mcc->hash_table[hash]; if (slot == MC_INVALID_VAL) { /* no previous record/collision, just add to hash table */ mcc->hash_table[hash] = MC_PTR_TO_SLOT(mcc->data_table, rec); return; } do { cur = MC_SLOT_TO_PTR(mcc->data_table, slot, struct sss_mc_rec); if (cur == rec) { /* rec already stored in hash chain */ return; } slot = sss_mc_next_slot_with_hash(cur, hash); } while (slot != MC_INVALID_VAL); /* end of chain, append our record here */ slot = MC_PTR_TO_SLOT(mcc->data_table, rec); sss_mc_chain_slot_to_record_with_hash(cur, hash, slot); }
static void sss_mc_rm_rec_from_chain(struct sss_mc_ctx *mcc, struct sss_mc_rec *rec, uint32_t hash) { struct sss_mc_rec *prev = NULL; struct sss_mc_rec *cur = NULL; uint32_t slot; if (hash > MC_HT_ELEMS(mcc->ht_size)) { /* It can happen if rec->hash1 and rec->hash2 was the same. * or it is invalid hash. It is better to return * than trying to access out of bounds memory */ return; } slot = mcc->hash_table[hash]; if (slot == MC_INVALID_VAL) { /* record has already been removed. It may happen if rec->hash1 and * rec->has2 are the same. (It is not very likely). */ return; } cur = MC_SLOT_TO_PTR(mcc->data_table, slot, struct sss_mc_rec); if (cur == rec) { mcc->hash_table[hash] = sss_mc_next_slot_with_hash(rec, hash); } else { slot = sss_mc_next_slot_with_hash(cur, hash); while (slot != MC_INVALID_VAL) { prev = cur; cur = MC_SLOT_TO_PTR(mcc->data_table, slot, struct sss_mc_rec); if (cur == rec) { slot = sss_mc_next_slot_with_hash(cur, hash); sss_mc_chain_slot_to_record_with_hash(prev, hash, slot); slot = MC_INVALID_VAL; } else { slot = sss_mc_next_slot_with_hash(cur, hash); } } } }
static uint32_t sss_mc_hash(struct sss_mc_ctx *mcc, const char *key, size_t len) { return murmurhash3(key, len, mcc->seed) % MC_HT_ELEMS(mcc->ht_size); }
uint32_t sss_nss_mc_hash(struct sss_cli_mc_ctx *ctx, const char *key, size_t len) { return murmurhash3(key, len, ctx->seed) % MC_HT_ELEMS(ctx->ht_size); }