Skip to content

Commit

Permalink
Get constant time (amortized) hash table access.
Browse files Browse the repository at this point in the history
  • Loading branch information
Keith Rarick committed Oct 16, 2008
1 parent eac1125 commit 6fd4f35
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 6 deletions.
49 changes: 45 additions & 4 deletions job.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -116,6 +155,8 @@ job_hash_free(job j)
}
}
}

all_jobs_used--;
}

void
Expand Down Expand Up @@ -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);
}
}
2 changes: 0 additions & 2 deletions job.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
74 changes: 74 additions & 0 deletions primes.c
Original file line number Diff line number Diff line change
@@ -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
};

27 changes: 27 additions & 0 deletions primes.h
Original file line number Diff line number Diff line change
@@ -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[];
Empty file added tests/test_primes.c
Empty file.

0 comments on commit 6fd4f35

Please sign in to comment.