Permalink
Browse files

Allow setting initial size of the hash table

Instances which run many millions of items can now have its hash table
presized. This can avoid some minor memory churn during the warmup
period.
  • Loading branch information...
1 parent 108e2cd commit 1db1de38283fdd3f5cdc556ac9ca9cb05892a75d @dormando dormando committed Sep 28, 2011
Showing with 39 additions and 6 deletions.
  1. +5 −2 assoc.c
  2. +1 −1 assoc.h
  3. +29 −3 memcached.c
  4. +4 −0 memcached.h
View
7 assoc.c
@@ -32,7 +32,7 @@ typedef unsigned long int ub4; /* unsigned 4-byte quantities */
typedef unsigned char ub1; /* unsigned 1-byte quantities */
/* how many powers of 2's worth of buckets we use */
-static unsigned int hashpower = 16;
+static unsigned int hashpower = HASHPOWER_DEFAULT;
#define hashsize(n) ((ub4)1<<(n))
#define hashmask(n) (hashsize(n)-1)
@@ -58,7 +58,10 @@ static bool expanding = false;
*/
static unsigned int expand_bucket = 0;
-void assoc_init(void) {
+void assoc_init(const int hashtable_init) {
+ if (hashtable_init) {
+ hashpower = hashtable_init;
+ }
primary_hashtable = calloc(hashsize(hashpower), sizeof(void *));
if (! primary_hashtable) {
fprintf(stderr, "Failed to init hashtable.\n");
View
2 assoc.h
@@ -1,5 +1,5 @@
/* associative array */
-void assoc_init(void);
+void assoc_init(const int hashpower_init);
item *assoc_find(const char *key, const size_t nkey);
int assoc_insert(item *item);
void assoc_delete(const char *key, const size_t nkey);
View
32 memcached.c
@@ -216,6 +216,7 @@ static void settings_init(void) {
settings.binding_protocol = negotiating_prot;
settings.item_size_max = 1024 * 1024; /* The famous 1MB upper limit. */
settings.maxconns_fast = false;
+ settings.hashpower_init = 0;
}
/*
@@ -2591,6 +2592,7 @@ static void process_stat_settings(ADD_STAT add_stats, void *c) {
APPEND_STAT("auth_enabled_sasl", "%s", settings.sasl ? "yes" : "no");
APPEND_STAT("item_size_max", "%d", settings.item_size_max);
APPEND_STAT("maxconns_fast", "%s", settings.maxconns_fast ? "yes" : "no");
+ APPEND_STAT("hashpower_init", "%d", settings.hashpower_init);
}
static void process_stat(conn *c, token_t *tokens, const size_t ntokens) {
@@ -4397,7 +4399,12 @@ static void usage(void) {
#endif
printf("-o Comma separated list of extended or experimental options\n"
" - (EXPERIMENTAL) maxconns_fast: immediately close new\n"
- " connections if over maxconns limit\n");
+ " connections if over maxconns limit\n"
+ " - hashpower: An integer multiplier for how large the hash\n"
+ " table should be. Can be grown at runtime if not big enough.\n"
+ " Set this based on \"STAT hash_power_level\" before a \n"
+ " restart.\n"
+ );
return;
}
@@ -4614,10 +4621,12 @@ int main (int argc, char **argv) {
char *subopts;
char *subopts_value;
enum {
- MAXCONNS_FAST = 0
+ MAXCONNS_FAST = 0,
+ HASHPOWER_INIT
};
char *const subopts_tokens[] = {
[MAXCONNS_FAST] = "maxconns_fast",
+ [HASHPOWER_INIT] = "hashpower",
NULL
};
@@ -4846,6 +4855,23 @@ int main (int argc, char **argv) {
case MAXCONNS_FAST:
settings.maxconns_fast = true;
break;
+ case HASHPOWER_INIT:
+ if (subopts_value == NULL) {
+ fprintf(stderr, "Missing numeric argument for hashpower\n");
+ return 1;
+ }
+ settings.hashpower_init = atoi(subopts_value);
+ if (settings.hashpower_init < 12) {
+ fprintf(stderr, "Initial hashtable multiplier of %d is too low\n",
+ settings.hashpower_init);
+ return 1;
+ } else if (settings.hashpower_init > 64) {
+ fprintf(stderr, "Initial hashtable multiplier of %d is too high\n"
+ "Choose a value based on \"STAT hash_power_level\" from a running instance\n",
+ settings.hashpower_init);
+ return 1;
+ }
+ break;
default:
printf("Illegal suboption \"%s\"\n", subopts_value);
return 1;
@@ -4979,7 +5005,7 @@ int main (int argc, char **argv) {
/* initialize other stuff */
stats_init();
- assoc_init();
+ assoc_init(settings.hashpower_init);
conn_init();
slabs_init(settings.maxbytes, settings.factor, preallocate);
View
4 memcached.h
@@ -60,6 +60,9 @@
#define MIN_BIN_PKT_LENGTH 16
#define BIN_PKT_HDR_WORDS (MIN_BIN_PKT_LENGTH/sizeof(uint32_t))
+/* Initial power multiplier for the hash table */
+#define HASHPOWER_DEFAULT 16
+
/* unistd.h is here */
#if HAVE_UNISTD_H
# include <unistd.h>
@@ -293,6 +296,7 @@ struct settings {
int item_size_max; /* Maximum item size, and upper end for slabs */
bool sasl; /* SASL on/off */
bool maxconns_fast; /* Whether or not to early close connections */
+ int hashpower_init; /* Starting hash power level */
};
extern struct stats stats;

0 comments on commit 1db1de3

Please sign in to comment.