int icdb_rehash(struct icdb *db) { struct icdbinfo *info = db->info; uint32_t entrysize = info->entrysize; uint32_t indexsize, idxmask, idxlen; int i, j; indexsize = info->indexsize = roundup(info->nentries); idxmask = indexsize - 1; idxlen = sizeof(uint32_t) * indexsize; arc4random_buf(&info->siphashkey, sizeof(info->siphashkey)); for (i = 0; i < info->nkeys; i++) { uint32_t *idxdata = reallocarray(db->idxdata[i], indexsize, sizeof(uint32_t)); if (!idxdata) return -1; memset(idxdata, 0xff, idxlen); db->idxdata[i] = idxdata; } for (j = 0; j < info->nentries; j++) { for (i = 0; i < info->nkeys; i++) { uint32_t *idxdata = db->idxdata[i]; uint64_t hash = SipHash24(&info->siphashkey, (uint8_t *)db->entries + j * entrysize + info->keyoffset[i], info->keysize[i]); while (idxdata[hash & idxmask] != -1) hash = SipHash24(&info->siphashkey, &hash, sizeof(hash)); idxdata[hash & idxmask] = j; } } return 0; }
int icdb_lookup(struct icdb *db, int keynum, const void *key, void *entry, uint32_t *idxp) { struct icdbinfo *info = db->info; uint32_t offset; uint64_t hash; uint32_t indexsize, idxmask, idxlen; uint32_t *idxdata; indexsize = info->indexsize; idxmask = indexsize - 1; idxlen = indexsize * sizeof(uint32_t); idxdata = db->idxdata[keynum]; hash = SipHash24(&info->siphashkey, key, info->keysize[keynum]); while ((offset = idxdata[hash & idxmask]) != -1) { if (icdb_get(db, entry, offset) != 0) { errno = ENOENT; return -1; } if (memcmp((uint8_t *)entry + info->keyoffset[keynum], key, info->keysize[keynum]) == 0) { if (idxp) *idxp = offset; return 0; } hash = SipHash24(&info->siphashkey, &hash, sizeof(hash)); } return 1; }
/* * Hash the specified filename into a dirhash slot. */ int ufsdirhash_hash(struct dirhash *dh, char *name, int namelen) { return SipHash24(&ufsdirhash_key, name, namelen) % dh->dh_hlen; }