Permalink
Browse files

Get constant time (amortized) hash table access.

  • Loading branch information...
1 parent eac1125 commit 6fd4f35212dbaa4995572632379b4fca278716e0 Keith Rarick committed Oct 16, 2008
Showing with 146 additions and 6 deletions.
  1. +45 −4 job.c
  2. +0 −2 job.h
  3. +74 −0 primes.c
  4. +27 −0 primes.h
  5. 0 tests/test_primes.c
View
49 job.c
@@ -21,16 +21,23 @@
#include "tube.h"
#include "job.h"
+#include "primes.h"
#include "util.h"
static unsigned long long int next_id = 1;
+static int cur_prime = 0;
+
static job *all_jobs=NULL;
+static size_t all_jobs_cap = 12289; /* == primes[0] */
+static size_t all_jobs_used = 0;
+
+static void rehash();
static int
_get_job_hash_index(unsigned long long int job_id)
{
- return job_id % NUM_JOB_BUCKETS;
+ return job_id % all_jobs_cap;
}
static void
@@ -41,8 +48,40 @@ store_job(job j)
index = _get_job_hash_index(j->id);
j->ht_next = all_jobs[index];
-
all_jobs[index] = j;
+ all_jobs_used++;
+
+ /* accept a load factor of 4 */
+ if (all_jobs_used > (all_jobs_cap << 2)) rehash();
+}
+
+static void
+rehash()
+{
+ job *old = all_jobs;
+ size_t old_cap = all_jobs_cap, old_used = all_jobs_used, i;
+
+ if (cur_prime >= NUM_PRIMES) return;
+
+ all_jobs_cap = primes[++cur_prime];
+ all_jobs = calloc(all_jobs_cap, sizeof(job));
+ if (!all_jobs) {
+ twarnx("Failed to allocate %d new hash buckets", all_jobs_cap);
+ --cur_prime;
+ all_jobs = old;
+ all_jobs_cap = old_cap;
+ all_jobs_used = old_used;
+ return;
+ }
+
+ for (i = 0; i < old_cap; i++) {
+ while (old[i]) {
+ job j = old[i];
+ old[i] = j->next;
+ j->next = NULL;
+ store_job(j);
+ }
+ }
}
job
@@ -116,6 +155,8 @@ job_hash_free(job j)
}
}
}
+
+ all_jobs_used--;
}
void
@@ -222,8 +263,8 @@ total_jobs()
void
job_init()
{
- all_jobs = calloc(NUM_JOB_BUCKETS, sizeof(job));
+ all_jobs = calloc(all_jobs_cap, sizeof(job));
if (!all_jobs) {
- twarnx("Failed to allocate %d hash buckets", NUM_JOB_BUCKETS);
+ twarnx("Failed to allocate %d hash buckets", all_jobs_cap);
}
}
View
2 job.h
@@ -52,8 +52,6 @@ struct job {
char body[];
};
-#define NUM_JOB_BUCKETS 12289
-
job allocate_job(int body_size);
job make_job(unsigned int pri, unsigned int delay, unsigned int ttr,
int body_size, tube tube);
View
@@ -0,0 +1,74 @@
+/* primes.c - exponentially increasing primes */
+
+/* Copyright (C) 2008 Keith Rarick and Philotic Inc.
+
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include "primes.h"
+
+size_t primes[] = {
+ 12289,
+ 24593,
+ 49193,
+ 98387,
+ 196799,
+ 393611,
+ 787243,
+ 1574491,
+ 3148987,
+ 6297979,
+ 12595991,
+ 25191989,
+ 50383981,
+ 100767977,
+ 201535967,
+ 403071937,
+ 806143879,
+ 1612287763,
+ 3224575537,
+#if _LP64
+ 6449151103,
+ 12898302233,
+ 25796604473,
+ 51593208973,
+ 103186417951,
+ 206372835917,
+ 412745671837,
+ 825491343683,
+ 1650982687391,
+ 3301965374803,
+ 6603930749621,
+ 13207861499251,
+ 26415722998507,
+ 52831445997037,
+ 105662891994103,
+ 211325783988211,
+ 422651567976461,
+ 845303135952931,
+ 1690606271905871,
+ 3381212543811743,
+ 6762425087623523,
+ 13524850175247127,
+ 27049700350494287,
+ 54099400700988593,
+ 108198801401977301,
+ 216397602803954641,
+ 432795205607909293,
+ 865590411215818597,
+ 1731180822431637217,
+#endif
+};
+
View
@@ -0,0 +1,27 @@
+/* primes.h - exponentially increasing primes */
+
+/* Copyright (C) 2008 Keith Rarick and Philotic Inc.
+
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+
+#if _LP64
+#define NUM_PRIMES 48
+#else
+#define NUM_PRIMES 19
+#endif
+
+extern size_t primes[];
View
No changes.

0 comments on commit 6fd4f35

Please sign in to comment.