mirror of
https://git.openafs.org/openafs.git
synced 2025-01-18 06:50:12 +00:00
opr: Allow non-2^x for n_buckets in opr_cache_init
Currently, opr_cache_init requires that opts->n_buckets is a power of 2 (since our underlying opr_dict requires this). However, callers may want to pick a number of buckets based on some other value. Requiring each caller to calculate the nearest power-of-2 is annoying, so instead just have opr_cache_init itself calculate a nearby power of 2. That is, with this commit, opts->n_buckets is allowed to not be a power of 2; when it's not a power of 2, opr_cache_init will calculate the next highest power of 2 and use that as the number of buckets. Change-Id: Icd3c56c1fe0733e3dac964ea9a98ff7b436254e6 Reviewed-on: https://gerrit.openafs.org/14122 Tested-by: BuildBot <buildbot@rampaginggeek.com> Reviewed-by: Marcio Brito Barbosa <mbarbosa@sinenomine.net> Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
This commit is contained in:
parent
3db8c37e8e
commit
19524a49d4
@ -356,6 +356,21 @@ isPowerOf2(int value)
|
||||
return (value > 0) && (value & (value - 1)) == 0;
|
||||
}
|
||||
|
||||
static_inline int
|
||||
nextPowerOf2(int target)
|
||||
{
|
||||
int next = 1;
|
||||
/*
|
||||
* Make sure we have a reasonable target and cannot overflow; callers
|
||||
* should do their own range checks before we get here.
|
||||
*/
|
||||
opr_Assert(target > 0 && target <= 0x40000000);
|
||||
while (next < target) {
|
||||
next *= 2;
|
||||
}
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new opr_cache.
|
||||
*
|
||||
@ -369,17 +384,20 @@ int
|
||||
opr_cache_init(struct opr_cache_opts *opts, struct opr_cache **a_cache)
|
||||
{
|
||||
struct opr_cache *cache;
|
||||
int n_buckets = opts->n_buckets;
|
||||
|
||||
if (opts->n_buckets < MIN_BUCKETS || opts->n_buckets > MAX_BUCKETS) {
|
||||
return EINVAL;
|
||||
}
|
||||
if (!isPowerOf2(opts->n_buckets)) {
|
||||
if (n_buckets < MIN_BUCKETS || n_buckets > MAX_BUCKETS) {
|
||||
return EINVAL;
|
||||
}
|
||||
if (opts->max_entries < MIN_ENTRIES || opts->max_entries > MAX_ENTRIES) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
n_buckets = nextPowerOf2(n_buckets);
|
||||
opr_Assert(isPowerOf2(n_buckets));
|
||||
opr_Assert(n_buckets >= MIN_BUCKETS);
|
||||
opr_Assert(n_buckets <= MAX_BUCKETS);
|
||||
|
||||
cache = calloc(1, sizeof(*cache));
|
||||
if (cache == NULL) {
|
||||
return ENOMEM;
|
||||
@ -388,7 +406,7 @@ opr_cache_init(struct opr_cache_opts *opts, struct opr_cache **a_cache)
|
||||
opr_mutex_init(&cache->lock);
|
||||
cache->max_entries = opts->max_entries;
|
||||
|
||||
cache->dict = opr_dict_Init(opts->n_buckets);
|
||||
cache->dict = opr_dict_Init(n_buckets);
|
||||
if (cache->dict == NULL) {
|
||||
opr_cache_free(&cache);
|
||||
return ENOMEM;
|
||||
|
@ -102,9 +102,27 @@ run_seed(int seed)
|
||||
ok(opr_cache_init(&opts, &cache) != 0,
|
||||
"Initializing a cache with a huge n_buckets fails");
|
||||
|
||||
opts.n_buckets = 23;
|
||||
opts.n_buckets = 1024*1024 + 1;
|
||||
ok(opr_cache_init(&opts, &cache) != 0,
|
||||
"Initializing a cache with non-power-of-2 n_buckets fails");
|
||||
"Initializing a cache with 1024*1024+1 n_buckets fails");
|
||||
|
||||
opts.n_buckets = 1024*1024;
|
||||
code = opr_cache_init(&opts, &cache);
|
||||
is_int(0, code,
|
||||
"Initializing a cache with 1024*1024 n_buckets succeeds");
|
||||
opr_cache_free(&cache);
|
||||
|
||||
opts.n_buckets = 1024*1024 - 1;
|
||||
code = opr_cache_init(&opts, &cache);
|
||||
is_int(0, code,
|
||||
"Initializing a cache with 1024*1024-1 n_buckets succeeds");
|
||||
opr_cache_free(&cache);
|
||||
|
||||
opts.n_buckets = 23;
|
||||
code = opr_cache_init(&opts, &cache);
|
||||
is_int(0, code,
|
||||
"Initializing a cache with non-power-of-2 n_buckets succeeds");
|
||||
opr_cache_free(&cache);
|
||||
|
||||
opts.n_buckets = 64;
|
||||
opts.max_entries = 1;
|
||||
@ -237,7 +255,7 @@ main(void)
|
||||
{
|
||||
int seed;
|
||||
|
||||
plan(113 * 32);
|
||||
plan(116 * 32);
|
||||
|
||||
for (seed = 0; seed < 32; seed++) {
|
||||
run_seed(seed);
|
||||
|
Loading…
Reference in New Issue
Block a user