blob: 64d78d1fb2cb77b2acf2eb8076cc8e406f5038f8 [file] [log] [blame]
//#if defined __INTEL_COMPILER
#include <stdio.h>
#define __USE_XOPEN
#include <stdlib.h>
#include "hash.h"
#include "genmalloc.h"
#ifdef HAVE_OPENCL
#include "hashlib_kern.inc"
#include "hashlib_source_kern.inc"
#endif
#ifndef NO_GLIBC_COMPAT_RAND
#include "glibc_compat_rand.h"
#define rand glibc_compat_rand
#define srand glibc_compat_srand
#define drand48() (1.0 * rand() / RAND_MAX)
#define srand48(x) srand(x)
#endif
static ulong AA;
static ulong BB;
static ulong prime=4294967291;
static uint hashtablesize;
static uint hash_stride;
static uint hash_ncells;
static uint write_hash_collisions;
static uint read_hash_collisions;
static double write_hash_collisions_runsum = 0.0;
static double read_hash_collisions_runsum = 0.0;
static uint write_hash_collisions_count = 0;
static uint read_hash_collisions_count = 0;
static uint hash_report_level = 2;
static uint hash_queries;
static int hash_method = METHOD_UNSET;
static uint hash_jump_prime = 41;
static double hash_mult = 3.0;
size_t hash_header_size = 16;
#ifdef HAVE_OPENCL
cl_mem dev_hash_header = NULL;
#endif
float mem_opt_factor;
int choose_hash_method = METHOD_UNSET;
#define MIN(a,b) ((a) < (b) ? (a) : (b))
int (*read_hash)(ulong, int *);
void (*write_hash)(uint, ulong, int *);
int get_hash_method(void) {
return(hash_method);
}
long long get_hashtablesize(void) {
return(hashtablesize);
}
int *compact_hash_init(int ncells, uint isize, uint jsize, uint report_level){
hash_ncells = 0;
write_hash_collisions = 0;
read_hash_collisions = 0;
hash_queries = 0;
hash_report_level = report_level;
hash_stride = isize;
int *hash = NULL;
if (choose_hash_method != METHOD_UNSET) hash_method = choose_hash_method;
uint compact_hash_size = (uint)((double)ncells*hash_mult);
uint perfect_hash_size = (uint)(isize*jsize);
if (hash_method == METHOD_UNSET){
float hash_mem_factor = 20.0;
float hash_mem_ratio = (double)perfect_hash_size/(double)compact_hash_size;
if (mem_opt_factor != 1.0) hash_mem_factor /= (mem_opt_factor*0.2);
hash_method = (hash_mem_ratio < hash_mem_factor) ? PERFECT_HASH : QUADRATIC;
if (hash_report_level >= 2) printf("DEBUG hash_method %d hash_mem_ratio %f hash_mem_factor %f mem_opt_factor %f perfect_hash_size %u compact_hash_size %u\n",
hash_method,hash_mem_ratio,hash_mem_factor,mem_opt_factor,perfect_hash_size,compact_hash_size);
}
int do_compact_hash = (hash_method == PERFECT_HASH) ? 0 : 1;
if (hash_report_level >= 2) printf("DEBUG do_compact_hash %d hash_method %d perfect_hash_size %u compact_hash_size %u\n",
do_compact_hash,hash_method,perfect_hash_size,compact_hash_size);
if (do_compact_hash) {
hashtablesize = compact_hash_size;
AA = (ulong)(1.0+(double)(prime-1)*drand48());
BB = (ulong)(0.0+(double)(prime-1)*drand48());
if (AA > prime-1 || BB > prime-1) exit(0);
if (hash_report_level > 1) printf("Factors AA %lu BB %lu\n",AA,BB);
hash = (int *)genvector(2*hashtablesize,sizeof(int));
for (uint ii = 0; ii<2*hashtablesize; ii+=2){
hash[ii] = -1;
}
if (hash_method == LINEAR){
if (hash_report_level == 0){
read_hash = read_hash_linear;
write_hash = write_hash_linear;
} else if (hash_report_level == 1){
read_hash = read_hash_linear_report_level_1;
write_hash = write_hash_linear_report_level_1;
} else if (hash_report_level == 2){
read_hash = read_hash_linear_report_level_2;
write_hash = write_hash_linear_report_level_2;
} else if (hash_report_level == 3){
read_hash = read_hash_linear_report_level_3;
write_hash = write_hash_linear_report_level_3;
}
} else if (hash_method == QUADRATIC) {
if (hash_report_level == 0){
read_hash = read_hash_quadratic;
write_hash = write_hash_quadratic;
} else if (hash_report_level == 1){
read_hash = read_hash_quadratic_report_level_1;
write_hash = write_hash_quadratic_report_level_1;
} else if (hash_report_level == 2){
read_hash = read_hash_quadratic_report_level_2;
write_hash = write_hash_quadratic_report_level_2;
} else if (hash_report_level == 3){
read_hash = read_hash_quadratic_report_level_3;
write_hash = write_hash_quadratic_report_level_3;
}
} else if (hash_method == PRIME_JUMP) {
if (hash_report_level == 0){
read_hash = read_hash_primejump;
write_hash = write_hash_primejump;
} else if (hash_report_level == 1){
read_hash = read_hash_primejump_report_level_1;
write_hash = write_hash_primejump_report_level_1;
} else if (hash_report_level == 2){
read_hash = read_hash_primejump_report_level_2;
write_hash = write_hash_primejump_report_level_2;
} else if (hash_report_level == 3){
read_hash = read_hash_primejump_report_level_3;
write_hash = write_hash_primejump_report_level_3;
}
}
} else {
hashtablesize = perfect_hash_size;
hash = (int *)genvector(hashtablesize,sizeof(int));
for (uint ii = 0; ii<hashtablesize; ii++){
hash[ii] = -1;
}
read_hash = read_hash_perfect;
write_hash = write_hash_perfect;
}
if (hash_report_level >= 2) {
printf("Hash table size %u perfect hash table size %u memory savings %d by percentage %lf\n",
hashtablesize,isize*jsize,(int)isize*(int)jsize-(int)hashtablesize,
(double)hashtablesize/(double)(isize*jsize) * 100.0);
}
return(hash);
}
#ifdef _OPENMP
int *compact_hash_init_openmp(int ncells, uint isize, uint jsize, uint report_level){
static int *hash = NULL;
static float hash_mem_factor;
static float hash_mem_ratio;
static int do_compact_hash;
static uint compact_hash_size;
static uint perfect_hash_size;
#pragma omp barrier
#pragma omp master
{
hash_ncells = 0;
write_hash_collisions = 0;
read_hash_collisions = 0;
hash_queries = 0;
hash_report_level = report_level;
hash_stride = isize;
if (choose_hash_method != METHOD_UNSET) hash_method = choose_hash_method;
compact_hash_size = (uint)((double)ncells*hash_mult);
perfect_hash_size = (uint)(isize*jsize);
if (hash_method == METHOD_UNSET){
hash_mem_factor = 20.0;
hash_mem_ratio = (double)perfect_hash_size/(double)compact_hash_size;
if (mem_opt_factor != 1.0) hash_mem_factor /= (mem_opt_factor*0.2);
hash_method = (hash_mem_ratio < hash_mem_factor) ? PERFECT_HASH : QUADRATIC;
//hash_method = QUADRATIC;
if (hash_report_level >= 2) printf("DEBUG hash_method %d hash_mem_ratio %f hash_mem_factor %f mem_opt_factor %f perfect_hash_size %u compact_hash_size %u\n",
hash_method,hash_mem_ratio,hash_mem_factor,mem_opt_factor,perfect_hash_size,compact_hash_size);
}
do_compact_hash = (hash_method == PERFECT_HASH) ? 0 : 1;
if (hash_report_level >= 2) printf("DEBUG do_compact_hash %d hash_method %d perfect_hash_size %u compact_hash_size %u\n",
do_compact_hash,hash_method,perfect_hash_size,compact_hash_size);
} // end omp master
#pragma omp barrier
if (do_compact_hash) {
#pragma omp master
{
hashtablesize = compact_hash_size;
//srand48(0);
AA = (ulong)(1.0+(double)(prime-1)*drand48());
BB = (ulong)(0.0+(double)(prime-1)*drand48());
if (AA > prime-1 || BB > prime-1) exit(0);
if (hash_report_level > 1) printf("Factors AA %lu BB %lu\n",AA,BB);
hash = (int *)genvector(2*hashtablesize,sizeof(int));
} // end omp master
#pragma omp barrier
#pragma omp for
for (uint ii = 0; ii<hashtablesize; ii++){
hash[2*ii] = -1;
}
#pragma omp master
{
if (hash_method == LINEAR){
if (hash_report_level == 0){
read_hash = read_hash_linear;
write_hash = write_hash_linear_openmp;
} else if (hash_report_level == 1){
read_hash = read_hash_linear_report_level_1;
write_hash = write_hash_linear_openmp_report_level_1;
} else if (hash_report_level == 2){
read_hash = read_hash_linear_report_level_2;
write_hash = write_hash_linear_openmp_report_level_2;
} else if (hash_report_level == 3){
read_hash = read_hash_linear_report_level_3;
write_hash = write_hash_linear_openmp_report_level_3;
}
} else if (hash_method == QUADRATIC) {
if (hash_report_level == 0){
read_hash = read_hash_quadratic;
write_hash = write_hash_quadratic_openmp;
} else if (hash_report_level == 1){
read_hash = read_hash_quadratic_report_level_1;
write_hash = write_hash_quadratic_openmp_report_level_1;
} else if (hash_report_level == 2){
read_hash = read_hash_quadratic_report_level_2;
write_hash = write_hash_quadratic_openmp_report_level_2;
} else if (hash_report_level == 3){
read_hash = read_hash_quadratic_report_level_3;
write_hash = write_hash_quadratic_openmp_report_level_3;
}
} else if (hash_method == PRIME_JUMP) {
if (hash_report_level == 0){
read_hash = read_hash_primejump;
write_hash = write_hash_primejump_openmp;
} else if (hash_report_level == 1){
read_hash = read_hash_primejump_report_level_1;
write_hash = write_hash_primejump_openmp_report_level_1;
} else if (hash_report_level == 2){
read_hash = read_hash_primejump_report_level_2;
write_hash = write_hash_primejump_openmp_report_level_2;
} else if (hash_report_level == 3){
read_hash = read_hash_primejump_report_level_3;
write_hash = write_hash_primejump_openmp_report_level_3;
}
}
} // end omp master
#pragma omp barrier
} else {
#pragma omp master
{
hashtablesize = perfect_hash_size;
hash = (int *)genvector(hashtablesize,sizeof(int));
} // end omp master
#pragma omp barrier
#pragma omp for
for (uint ii = 0; ii<hashtablesize; ii++){
hash[ii] = -1;
}
#pragma omp master
{
read_hash = read_hash_perfect;
write_hash = write_hash_perfect;
} // end omp master
#pragma omp barrier
}
#pragma omp master
{
if (hash_report_level >= 2) {
printf("Hash table size %u perfect hash table size %u memory savings %u by percentage %lf\n",
hashtablesize,isize*jsize,isize*jsize-hashtablesize,
(double)hashtablesize/(double)(isize*jsize));
}
}
#pragma omp barrier
return(hash);
}
#endif
void write_hash_perfect(uint ic, ulong hashkey, int *hash){
hash[hashkey] = ic;
}
void write_hash_linear(uint ic, ulong hashkey, int *hash){
uint hashloc;
for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != -1 && hash[2*hashloc]!= (int)hashkey; hashloc++,hashloc = hashloc%hashtablesize);
hash[2*hashloc] = hashkey;
hash[2*hashloc+1] = ic;
}
void write_hash_linear_report_level_1(uint ic, ulong hashkey, int *hash){
uint hashloc;
hash_ncells++;
for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != -1 && hash[2*hashloc]!= (int)hashkey; hashloc++,hashloc = hashloc%hashtablesize){
write_hash_collisions++;
}
hash[2*hashloc] = hashkey;
hash[2*hashloc+1] = ic;
}
void write_hash_linear_report_level_2(uint ic, ulong hashkey, int *hash){
uint hashloc;
hash_ncells++;
for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != -1 && hash[2*hashloc]!= (int)hashkey; hashloc++,hashloc = hashloc%hashtablesize){
write_hash_collisions++;
}
hash[2*hashloc] = hashkey;
hash[2*hashloc+1] = ic;
}
void write_hash_linear_report_level_3(uint ic, ulong hashkey, int *hash){
int icount = 0;
uint hashloc;
hash_ncells++;
hashloc = (hashkey*AA+BB)%prime%hashtablesize;
printf("%d: cell %d hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,ic,hashloc,hash[2*hashloc],hashkey,hashkey%hash_stride,hashkey/hash_stride);
for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != -1 && hash[2*hashloc]!= (int)hashkey; hashloc++,hashloc = hashloc%hashtablesize){
int hashloctmp = hashloc+1;
hashloctmp = hashloctmp%hashtablesize;
printf("%d: cell %d hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,ic,hashloctmp,hash[2*hashloctmp],hashkey,hashkey%hash_stride,hashkey/hash_stride);
icount++;
}
write_hash_collisions += icount;
hash[2*hashloc] = hashkey;
hash[2*hashloc+1] = ic;
}
void write_hash_quadratic(uint ic, ulong hashkey, int *hash){
int icount = 0;
uint hashloc;
for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != -1 && hash[2*hashloc]!= (int)hashkey; hashloc+=(icount*icount),hashloc = hashloc%hashtablesize) {
icount++;
}
hash[2*hashloc] = hashkey;
hash[2*hashloc+1] = ic;
}
void write_hash_quadratic_report_level_1(uint ic, ulong hashkey, int *hash){
int icount = 0;
uint hashloc;
hash_ncells++;
for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != -1 && hash[2*hashloc]!= (int)hashkey; hashloc+=(icount*icount),hashloc = hashloc%hashtablesize){
icount++;
}
write_hash_collisions += icount;
hash[2*hashloc] = hashkey;
hash[2*hashloc+1] = ic;
}
void write_hash_quadratic_report_level_2(uint ic, ulong hashkey, int *hash){
int icount = 0;
uint hashloc;
hash_ncells++;
for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != -1 && hash[2*hashloc]!= (int)hashkey; hashloc+=(icount*icount),hashloc = hashloc%hashtablesize){
icount++;
}
write_hash_collisions += icount;
hash[2*hashloc] = hashkey;
hash[2*hashloc+1] = ic;
}
void write_hash_quadratic_report_level_3(uint ic, ulong hashkey, int *hash){
int icount = 0;
uint hashloc;
hash_ncells++;
hashloc = (hashkey*AA+BB)%prime%hashtablesize;
printf("%d: cell %d hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,ic,hashloc,hash[2*hashloc],hashkey,hashkey%hash_stride,hashkey/hash_stride);
for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != -1 && hash[2*hashloc]!= (int)hashkey; hashloc+=(icount*icount),hashloc = hashloc%hashtablesize){
icount++;
int hashloctmp = hashloc+icount*icount;
hashloctmp = hashloctmp%hashtablesize;
printf("%d: cell %d hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,ic,hashloctmp,hash[2*hashloctmp],hashkey,hashkey%hash_stride,hashkey/hash_stride);
}
write_hash_collisions += icount;
hash[2*hashloc] = hashkey;
hash[2*hashloc+1] = ic;
}
void write_hash_primejump(uint ic, ulong hashkey, int *hash){
int icount = 0;
uint hashloc;
uint jump = 1+hashkey%hash_jump_prime;
for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != -1 && hash[2*hashloc]!= (int)hashkey; hashloc+=(icount*jump),hashloc = hashloc%hashtablesize) {
icount++;
}
hash[2*hashloc] = hashkey;
hash[2*hashloc+1] = ic;
}
void write_hash_primejump_report_level_1(uint ic, ulong hashkey, int *hash){
int icount = 0;
uint hashloc;
uint jump = 1+hashkey%hash_jump_prime;
hash_ncells++;
for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != -1 && hash[2*hashloc]!= (int)hashkey; hashloc+=(icount*jump),hashloc = hashloc%hashtablesize){
icount++;
}
write_hash_collisions += icount;
hash[2*hashloc] = hashkey;
hash[2*hashloc+1] = ic;
}
void write_hash_primejump_report_level_2(uint ic, ulong hashkey, int *hash){
int icount = 0;
uint hashloc;
uint jump = 1+hashkey%hash_jump_prime;
hash_ncells++;
for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != -1 && hash[2*hashloc]!= (int)hashkey; hashloc+=(icount*jump),hashloc = hashloc%hashtablesize){
icount++;
}
write_hash_collisions += icount;
hash[2*hashloc] = hashkey;
hash[2*hashloc+1] = ic;
}
void write_hash_primejump_report_level_3(uint ic, ulong hashkey, int *hash){
int icount = 0;
uint hashloc;
uint jump = 1+hashkey%hash_jump_prime;
hash_ncells++;
hashloc = (hashkey*AA+BB)%prime%hashtablesize;
printf("%d: cell %d hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,ic,hashloc,hash[2*hashloc],hashkey,hashkey%hash_stride,hashkey/hash_stride);
for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != -1 && hash[2*hashloc]!= (int)hashkey; hashloc+=(icount*jump),hashloc = hashloc%hashtablesize){
icount++;
int hashloctmp = hashloc+1;
hashloctmp = hashloctmp%hashtablesize;
printf("%d: cell %d hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,ic,hashloctmp,hash[2*hashloctmp],hashkey,hashkey%hash_stride,hashkey/hash_stride);
}
write_hash_collisions += icount;
hash[2*hashloc] = hashkey;
hash[2*hashloc+1] = ic;
}
#ifdef _OPENMP
void write_hash_linear_openmp(uint ic, ulong hashkey, int *hash){
int icount;
uint hashloc = (hashkey*AA+BB)%prime%hashtablesize;;
int MaxTries = 1000;
int old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
//printf("old_key is %d\n",old_key);
for (icount = 1; old_key != hashkey && old_key != -1 && icount < MaxTries; icount++){
hashloc++;
hashloc %= hashtablesize;
old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
}
if (icount < MaxTries) hash[2*hashloc+1] = ic;
}
void write_hash_linear_openmp_report_level_1(uint ic, ulong hashkey, int *hash){
int icount = 0;
uint hashloc = (hashkey*AA+BB)%prime%hashtablesize;;
int MaxTries = 1000;
int old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
//printf("old_key is %d\n",old_key);
for (icount = 1; old_key != hashkey && old_key != -1 && icount < MaxTries; icount++){
hashloc++;
hashloc %= hashtablesize;
old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
icount++;
}
if (icount < MaxTries) hash[2*hashloc+1] = ic;
#pragma omp atomic
write_hash_collisions += icount;;
#pragma omp atomic
hash_ncells++;
}
void write_hash_linear_openmp_report_level_2(uint ic, ulong hashkey, int *hash){
int icount = 0;
uint hashloc = (hashkey*AA+BB)%prime%hashtablesize;;
int MaxTries = 1000;
int old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
//printf("old_key is %d\n",old_key);
for (icount = 1; old_key != hashkey && old_key != -1 && icount < MaxTries; icount++){
hashloc++;
hashloc %= hashtablesize;
old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
icount++;
}
if (icount < MaxTries) hash[2*hashloc+1] = ic;
#pragma omp atomic
write_hash_collisions += icount;;
#pragma omp atomic
hash_ncells++;
}
void write_hash_linear_openmp_report_level_3(uint ic, ulong hashkey, int *hash){
int icount = 0;
uint hashloc = (hashkey*AA+BB)%prime%hashtablesize;;
printf("%d: cell %d hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,ic,hashloc,hash[2*hashloc],hashkey,hashkey%hash_stride,hashkey/hash_stride);
int MaxTries = 1000;
int old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
//printf("old_key is %d\n",old_key);
for (icount = 1; old_key != hashkey && old_key != -1 && icount < MaxTries; icount++){
hashloc++;
hashloc %= hashtablesize;
printf("%d: cell %d hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,ic,hashloc,hash[2*hashloc],hashkey,hashkey%hash_stride,hashkey/hash_stride);
old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
icount++;
}
if (icount < MaxTries) hash[2*hashloc+1] = ic;
#pragma omp atomic
write_hash_collisions += icount;;
#pragma omp atomic
hash_ncells++;
}
void write_hash_quadratic_openmp(uint ic, ulong hashkey, int *hash){
int icount = 0;
uint hashloc = (hashkey*AA+BB)%prime%hashtablesize;
int MaxTries = 1000;
int old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
//printf("old_key is %d\n",old_key);
for (icount = 1; old_key != hashkey && old_key != -1 && icount < MaxTries; icount++){
hashloc+=(icount*icount);
hashloc %= hashtablesize;
old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
}
if (icount < MaxTries) hash[2*hashloc+1] = ic;
}
void write_hash_quadratic_openmp_report_level_1(uint ic, ulong hashkey, int *hash){
int icount = 0;
uint hashloc = (hashkey*AA+BB)%prime%hashtablesize;
int MaxTries = 1000;
int old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
//printf("old_key is %d\n",old_key);
for (icount = 1; old_key != hashkey && old_key != -1 && icount < MaxTries; icount++){
hashloc+=(icount*icount);
hashloc %= hashtablesize;
old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
}
if (icount < MaxTries) hash[2*hashloc+1] = ic;
#pragma omp atomic
write_hash_collisions += icount;;
#pragma omp atomic
hash_ncells++;
}
void write_hash_quadratic_openmp_report_level_2(uint ic, ulong hashkey, int *hash){
int icount = 0;
uint hashloc = (hashkey*AA+BB)%prime%hashtablesize;
int MaxTries = 1000;
int old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
//printf("old_key is %d\n",old_key);
for (icount = 1; old_key != hashkey && old_key != -1 && icount < MaxTries; icount++){
hashloc+=(icount*icount);
hashloc %= hashtablesize;
old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
}
if (icount < MaxTries) hash[2*hashloc+1] = ic;
#pragma omp atomic
write_hash_collisions += icount;;
#pragma omp atomic
hash_ncells++;
}
void write_hash_quadratic_openmp_report_level_3(uint ic, ulong hashkey, int *hash){
int icount = 0;
uint hashloc = (hashkey*AA+BB)%prime%hashtablesize;
printf("%d: cell %d hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,ic,hashloc,hash[2*hashloc],hashkey,hashkey%hash_stride,hashkey/hash_stride);
int MaxTries = 1000;
int old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
//printf("old_key is %d\n",old_key);
for (icount = 1; old_key != hashkey && old_key != -1 && icount < MaxTries; icount++){
hashloc+=(icount*icount);
hashloc %= hashtablesize;
printf("%d: cell %d hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,ic,hashloc,hash[2*hashloc],hashkey,hashkey%hash_stride,hashkey/hash_stride);
old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
}
if (icount < MaxTries) hash[2*hashloc+1] = ic;
#pragma omp atomic
write_hash_collisions += icount;;
#pragma omp atomic
hash_ncells++;
}
void write_hash_primejump_openmp(uint ic, ulong hashkey, int *hash){
int icount = 0;
uint jump = 1+hashkey%hash_jump_prime;
uint hashloc = (hashkey*AA+BB)%prime%hashtablesize;
int MaxTries = 1000;
int old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
//printf("old_key is %d\n",old_key);
for (icount = 1; old_key != hashkey && old_key != -1 && icount < MaxTries; icount++){
hashloc+=(icount*jump);
hashloc %= hashtablesize;
old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
}
if (icount < MaxTries) hash[2*hashloc+1] = ic;
}
void write_hash_primejump_openmp_report_level_1(uint ic, ulong hashkey, int *hash){
int icount = 0;
uint jump = 1+hashkey%hash_jump_prime;
uint hashloc = (hashkey*AA+BB)%prime%hashtablesize;
int MaxTries = 1000;
int old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
//printf("old_key is %d\n",old_key);
for (icount = 1; old_key != hashkey && old_key != -1 && icount < MaxTries; icount++){
hashloc+=(icount*jump);
hashloc %= hashtablesize;
old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
}
if (icount < MaxTries) hash[2*hashloc+1] = ic;
#pragma omp atomic
write_hash_collisions += icount;;
#pragma omp atomic
hash_ncells++;
}
void write_hash_primejump_openmp_report_level_2(uint ic, ulong hashkey, int *hash){
int icount = 0;
uint jump = 1+hashkey%hash_jump_prime;
uint hashloc = (hashkey*AA+BB)%prime%hashtablesize;
int MaxTries = 1000;
int old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
//printf("old_key is %d\n",old_key);
for (icount = 1; old_key != hashkey && old_key != -1 && icount < MaxTries; icount++){
hashloc+=(icount*jump);
hashloc %= hashtablesize;
old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
}
if (icount < MaxTries) hash[2*hashloc+1] = ic;
#pragma omp atomic
write_hash_collisions += icount;;
#pragma omp atomic
hash_ncells++;
}
void write_hash_primejump_openmp_report_level_3(uint ic, ulong hashkey, int *hash){
int icount = 0;
uint jump = 1+hashkey%hash_jump_prime;
uint hashloc = (hashkey*AA+BB)%prime%hashtablesize;
printf("%d: cell %d hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,ic,hashloc,hash[2*hashloc],hashkey,hashkey%hash_stride,hashkey/hash_stride);
int MaxTries = 1000;
int old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
//printf("old_key is %d\n",old_key);
for (icount = 1; old_key != hashkey && old_key != -1 && icount < MaxTries; icount++){
hashloc+=(icount*jump);
hashloc %= hashtablesize;
printf("%d: cell %d hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,ic,hashloc,hash[2*hashloc],hashkey,hashkey%hash_stride,hashkey/hash_stride);
old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
}
if (icount < MaxTries) hash[2*hashloc+1] = ic;
#pragma omp atomic
write_hash_collisions += icount;;
#pragma omp atomic
hash_ncells++;
}
#endif
int read_hash_perfect(ulong hashkey, int *hash){
return(hash[hashkey]);
}
int read_hash_linear(ulong hashkey, int *hash){
int hashval = -1;
uint hashloc;
int icount=0;
for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc++,hashloc = hashloc%hashtablesize){
icount++;
}
if (hash[2*hashloc] != -1) hashval = hash[2*hashloc+1];
return(hashval);
}
int read_hash_linear_report_level_1(ulong hashkey, int *hash){
int hashval = -1;
uint hashloc;
int icount=0;
hash_queries++;
for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc++,hashloc = hashloc%hashtablesize){
icount++;
}
read_hash_collisions += icount;
if (hash[2*hashloc] != -1) hashval = hash[2*hashloc+1];
return(hashval);
}
int read_hash_linear_report_level_2(ulong hashkey, int *hash){
int max_collisions_allowed = 1000;
int hashval = -1;
uint hashloc;
int icount=0;
hash_queries++;
for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc++,hashloc = hashloc%hashtablesize){
icount++;
if (icount > max_collisions_allowed) {
printf("Error -- too many read hash collisions\n");
exit(0);
}
}
read_hash_collisions += icount;
if (hash[2*hashloc] != -1) hashval = hash[2*hashloc+1];
return(hashval);
}
int read_hash_linear_report_level_3(ulong hashkey, int *hash){
int max_collisions_allowed = 1000;
int hashval = -1;
uint hashloc;
int icount=0;
hash_queries++;
hashloc = (hashkey*AA+BB)%prime%hashtablesize;
printf("%d: hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,hashloc,hash[2*hashloc],hashkey,hashkey%hash_stride,hashkey/hash_stride);
for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc++,hashloc = hashloc%hashtablesize){
icount++;
uint hashloctmp = hashloc+1;
hashloctmp = hashloctmp%hashtablesize;
printf("%d: hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,hashloctmp,hash[2*hashloctmp],hashkey,hashkey%hash_stride,hashkey/hash_stride);
if (icount > max_collisions_allowed) {
printf("Error -- too many read hash collisions\n");
exit(0);
}
}
read_hash_collisions += icount;
if (hash[2*hashloc] != -1) hashval = hash[2*hashloc+1];
return(hashval);
}
int read_hash_quadratic(ulong hashkey, int *hash){
int hashval = -1;
uint hashloc;
int icount=0;
for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc+=(icount*icount),hashloc = hashloc%hashtablesize){
icount++;
}
if (hash[2*hashloc] != -1) hashval = hash[2*hashloc+1];
return(hashval);
}
int read_hash_quadratic_report_level_1(ulong hashkey, int *hash){
int hashval = -1;
uint hashloc;
int icount=0;
hash_queries++;
for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc+=(icount*icount),hashloc = hashloc%hashtablesize){
icount++;
}
read_hash_collisions += icount;
if (hash[2*hashloc] != -1) hashval = hash[2*hashloc+1];
return(hashval);
}
int read_hash_quadratic_report_level_2(ulong hashkey, int *hash){
int max_collisions_allowed = 1000;
int hashval = -1;
uint hashloc;
int icount=0;
hash_queries++;
for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc+=(icount*icount),hashloc = hashloc%hashtablesize){
icount++;
if (icount > max_collisions_allowed) {
printf("Error -- too many read hash collisions\n");
exit(0);
}
}
read_hash_collisions += icount;
if (hash[2*hashloc] != -1) hashval = hash[2*hashloc+1];
return(hashval);
}
int read_hash_quadratic_report_level_3(ulong hashkey, int *hash){
int max_collisions_allowed = 1000;
int hashval = -1;
uint hashloc;
int icount=0;
hash_queries++;
hashloc = (hashkey*AA+BB)%prime%hashtablesize;
printf("%d: hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,hashloc,hash[2*hashloc],hashkey,hashkey%hash_stride,hashkey/hash_stride);
for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc+=(icount*icount),hashloc = hashloc%hashtablesize){
icount++;
uint hashloctmp = hashloc+1;
hashloctmp = hashloctmp%hashtablesize;
printf("%d: hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,hashloctmp,hash[2*hashloctmp],hashkey,hashkey%hash_stride,hashkey/hash_stride);
if (icount > max_collisions_allowed) {
printf("Error -- too many read hash collisions\n");
exit(0);
}
}
read_hash_collisions += icount;
if (hash[2*hashloc] != -1) hashval = hash[2*hashloc+1];
return(hashval);
}
int read_hash_primejump(ulong hashkey, int *hash){
int hashval = -1;
uint hashloc;
int icount=0;
uint jump = 1+hashkey%hash_jump_prime;
for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc+=(icount*jump),hashloc = hashloc%hashtablesize){
icount++;
}
if (hash[2*hashloc] != -1) hashval = hash[2*hashloc+1];
return(hashval);
}
int read_hash_primejump_report_level_1(ulong hashkey, int *hash){
int hashval = -1;
uint hashloc;
int icount=0;
uint jump = 1+hashkey%hash_jump_prime;
hash_queries++;
for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc+=(icount*jump),hashloc = hashloc%hashtablesize){
icount++;
}
read_hash_collisions += icount;
if (hash[2*hashloc] != -1) hashval = hash[2*hashloc+1];
return(hashval);
}
int read_hash_primejump_report_level_2(ulong hashkey, int *hash){
int max_collisions_allowed = 1000;
int hashval = -1;
uint hashloc;
int icount=0;
uint jump = 1+hashkey%hash_jump_prime;
hash_queries++;
for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc+=(icount*jump),hashloc = hashloc%hashtablesize){
icount++;
if (icount > max_collisions_allowed) {
printf("Error -- too many read hash collisions\n");
exit(0);
}
}
read_hash_collisions += icount;
if (hash[2*hashloc] != -1) hashval = hash[2*hashloc+1];
return(hashval);
}
int read_hash_primejump_report_level_3(ulong hashkey, int *hash){
int max_collisions_allowed = 1000;
int hashval = -1;
uint hashloc;
int icount=0;
uint jump = 1+hashkey%hash_jump_prime;
hash_queries++;
hashloc = (hashkey*AA+BB)%prime%hashtablesize;
printf("%d: hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,hashloc,hash[2*hashloc],hashkey,hashkey%hash_stride,hashkey/hash_stride);
for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc+=(icount*jump),hashloc = hashloc%hashtablesize){
icount++;
uint hashloctmp = hashloc+1;
hashloctmp = hashloctmp%hashtablesize;
printf("%d: hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,hashloctmp,hash[2*hashloctmp],hashkey,hashkey%hash_stride,hashkey/hash_stride);
if (icount > max_collisions_allowed) {
printf("Error -- too many read hash collisions\n");
exit(0);
}
}
read_hash_collisions += icount;
if (hash[2*hashloc] != -1) hashval = hash[2*hashloc+1];
return(hashval);
}
void compact_hash_delete(int *hash){
read_hash = NULL;
genvectorfree((void *)hash);
hash_method = METHOD_UNSET;
}
void write_hash_collision_report(void){
if (hash_method == PERFECT_HASH) return;
if (hash_report_level == 1) {
write_hash_collisions_runsum += (double)write_hash_collisions/(double)hash_ncells;
write_hash_collisions_count++;
} else if (hash_report_level >= 2) {
printf("Write hash collision report -- collisions per cell %lf, collisions %d cells %d\n",(double)write_hash_collisions/(double)hash_ncells,write_hash_collisions,hash_ncells);
}
}
void read_hash_collision_report(void){
//printf("hash table size bytes %ld\n",hashtablesize*sizeof(int));
if (hash_method == PERFECT_HASH) return;
if (hash_report_level == 1) {
read_hash_collisions_runsum += (double)read_hash_collisions/(double)hash_queries;
read_hash_collisions_count++;
} else if (hash_report_level >= 2) {
printf("Read hash collision report -- collisions per cell %lf, collisions %d cells %d\n",(double)read_hash_collisions/(double)hash_queries,read_hash_collisions,hash_queries);
hash_queries = 0;
read_hash_collisions = 0;
}
}
void final_hash_collision_report(void){
printf("hash table size bytes %ld\n",hashtablesize*sizeof(int));
if (hash_report_level >= 1 && read_hash_collisions_count > 0) {
printf("Final hash collision report -- write/read collisions per cell %lf/%lf\n",write_hash_collisions_runsum/(double)write_hash_collisions_count,read_hash_collisions_runsum/(double)read_hash_collisions_count);
}
}
#ifdef HAVE_OPENCL
const char *get_hash_kernel_source_string(void)
{
return(hashlib_source_kern_source);
}
#endif
#ifdef HAVE_OPENCL
static cl_kernel kernel_hash_init;
void hash_lib_init(void){
cl_context context = ezcl_get_context();
const char *defines = NULL;
cl_program program = ezcl_create_program_wsource(context, defines, hashlib_kern_source);
kernel_hash_init = ezcl_create_kernel_wprogram(program, "hash_init_cl");
ezcl_program_release(program);
}
void hash_lib_terminate(void){
ezcl_kernel_release(kernel_hash_init);
}
cl_mem gpu_compact_hash_init(ulong ncells, int imaxsize, int jmaxsize, int gpu_hash_method, uint hash_report_level_in,
ulong *gpu_hashtablesize, ulong *hashsize, cl_mem *dev_hash_header_in)
{
hash_report_level = hash_report_level_in;
uint gpu_compact_hash_size = (uint)((double)ncells*hash_mult);
uint gpu_perfect_hash_size = (uint)(imaxsize*jmaxsize);
if (gpu_hash_method == METHOD_UNSET) {
float gpu_hash_mem_factor = 20.0;
float gpu_hash_mem_ratio = (double)gpu_perfect_hash_size/(double)gpu_compact_hash_size;
if (mem_opt_factor != 1.0) gpu_hash_mem_factor /= (mem_opt_factor*0.2);
gpu_hash_method = (gpu_hash_mem_ratio < gpu_hash_mem_factor) ? PERFECT_HASH : QUADRATIC;
}
int gpu_do_compact_hash = (gpu_hash_method == PERFECT_HASH) ? 0 : 1;
ulong gpu_AA = 1;
ulong gpu_BB = 0;
if (gpu_do_compact_hash){
(*gpu_hashtablesize) = gpu_compact_hash_size;
gpu_AA = (ulong)(1.0+(double)(prime-1)*drand48());
gpu_BB = (ulong)(0.0+(double)(prime-1)*drand48());
//if ( gpu_AA > prime-1 || gpu_BB > prime-1) exit(0);
(*hashsize) = 2*gpu_compact_hash_size;
} else {
(*gpu_hashtablesize) = gpu_perfect_hash_size;
(*hashsize) = gpu_perfect_hash_size;
}
hashtablesize = (*hashsize);
const uint TILE_SIZE = 128;
cl_command_queue command_queue = ezcl_get_command_queue();
cl_mem dev_hash = ezcl_malloc(NULL, "dev_hash", hashsize, sizeof(cl_int), CL_MEM_READ_WRITE, 0);
ulong *gpu_hash_header = (ulong *)genvector(hash_header_size, sizeof(ulong));
gpu_hash_header[0] = (ulong)gpu_hash_method;
gpu_hash_header[1] = (*gpu_hashtablesize);
gpu_hash_header[2] = gpu_AA;
gpu_hash_header[3] = gpu_BB;
dev_hash_header = ezcl_malloc(NULL, "dev_hash_header", &hash_header_size, sizeof(cl_ulong), CL_MEM_READ_WRITE, 0);
ezcl_enqueue_write_buffer(command_queue, dev_hash_header, CL_TRUE, 0, hash_header_size*sizeof(cl_ulong), &gpu_hash_header[0], NULL);
genvectorfree(gpu_hash_header);
(*dev_hash_header_in) = dev_hash_header;
size_t hash_local_work_size = MIN((*hashsize), TILE_SIZE);
size_t hash_global_work_size = (((*hashsize)+hash_local_work_size - 1) /hash_local_work_size) * hash_local_work_size;
ezcl_set_kernel_arg(kernel_hash_init, 0, sizeof(cl_int), (void *)hashsize);
ezcl_set_kernel_arg(kernel_hash_init, 1, sizeof(cl_mem), (void *)&dev_hash);
ezcl_enqueue_ndrange_kernel(command_queue, kernel_hash_init, 1, NULL, &hash_global_work_size, &hash_local_work_size, NULL);
return(dev_hash);
}
void gpu_compact_hash_delete(cl_mem dev_hash, cl_mem dev_hash_header){
ezcl_device_memory_delete(dev_hash);
ezcl_device_memory_delete(dev_hash_header);
hash_method = METHOD_UNSET;
}
cl_mem gpu_get_hash_header(void){
return(dev_hash_header);
}
#endif
int read_dev_hash(int hash_method, ulong hashtablesize, ulong AA, ulong BB, ulong hashkey, int *hash){
//int hash_report_level = 3;
int max_collisions_allowed = 1000;
int hashval = -1;
uint hashloc;
int icount=0;
if (hash_method == PERFECT_HASH) {
return(hash[hashkey]);
}
if (hash_method == LINEAR) {
if (hash_report_level == 0) {
for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc++,hashloc = hashloc%hashtablesize){
icount++;
}
} else if (hash_report_level == 1) {
hash_queries++;
for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc++,hashloc = hashloc%hashtablesize){
icount++;
}
read_hash_collisions += icount;
} else if (hash_report_level == 2) {
hash_queries++;
for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc++,hashloc = hashloc%hashtablesize){
icount++;
if (icount > max_collisions_allowed) {
printf("Error -- too many read hash collisions\n");
exit(0);
}
}
read_hash_collisions += icount;
} else if (hash_report_level == 3) {
hash_queries++;
hashloc = (hashkey*AA+BB)%prime%hashtablesize;
printf("%d: hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,hashloc,hash[2*hashloc],hashkey,hashkey%hash_stride,hashkey/hash_stride);
for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc++,hashloc = hashloc%hashtablesize){
icount++;
uint hashloctmp = hashloc+1;
hashloctmp = hashloctmp%hashtablesize;
printf("%d: hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,hashloctmp,hash[2*hashloctmp],hashkey,hashkey%hash_stride,hashkey/hash_stride);
if (icount > max_collisions_allowed) {
printf("Error -- too many read hash collisions\n");
exit(0);
}
}
read_hash_collisions += icount;
} else {
printf("Error -- Illegal value of hash_report_level %d\n",hash_report_level);
exit(1);
}
} else if (hash_method == QUADRATIC) {
if (hash_report_level == 0) {
for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc+=(icount*icount),hashloc = hashloc%hashtablesize){
icount++;
}
} else if (hash_report_level == 1) {
hash_queries++;
for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc+=(icount*icount),hashloc = hashloc%hashtablesize){
icount++;
}
read_hash_collisions += icount;
} else if (hash_report_level == 2) {
hash_queries++;
for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc+=(icount*icount),hashloc = hashloc%hashtablesize){
icount++;
if (icount > max_collisions_allowed) {
printf("Error -- too many read hash collisions\n");
exit(0);
}
}
read_hash_collisions += icount;
} else if (hash_report_level == 3) {
hash_queries++;
hashloc = (hashkey*AA+BB)%prime%hashtablesize;
printf("%d: hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,hashloc,hash[2*hashloc],hashkey,hashkey%hash_stride,hashkey/hash_stride);
for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc+=(icount*icount),hashloc = hashloc%hashtablesize){
icount++;
uint hashloctmp = hashloc+1;
hashloctmp = hashloctmp%hashtablesize;
printf("%d: hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,hashloctmp,hash[2*hashloctmp],hashkey,hashkey%hash_stride,hashkey/hash_stride);
if (icount > max_collisions_allowed) {
printf("Error -- too many read hash collisions\n");
exit(0);
}
}
read_hash_collisions += icount;
} else {
printf("Error -- Illegal value of hash_report_level %d\n",hash_report_level);
exit(1);
}
} else if (hash_method == PRIME_JUMP) {
uint jump = 1+hashkey%hash_jump_prime;
if (hash_report_level == 0) {
for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc+=(icount*jump),hashloc = hashloc%hashtablesize){
icount++;
}
} else if (hash_report_level == 1) {
hash_queries++;
for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc+=(icount*jump),hashloc = hashloc%hashtablesize){
icount++;
}
read_hash_collisions += icount;
} else if (hash_report_level == 2) {
hash_queries++;
for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc+=(icount*jump),hashloc = hashloc%hashtablesize){
icount++;
if (icount > max_collisions_allowed) {
printf("Error -- too many read hash collisions\n");
exit(0);
}
}
read_hash_collisions += icount;
} else if (hash_report_level == 3) {
hash_queries++;
hashloc = (hashkey*AA+BB)%prime%hashtablesize;
printf("%d: hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,hashloc,hash[2*hashloc],hashkey,hashkey%hash_stride,hashkey/hash_stride);
for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc+=(icount*jump),hashloc = hashloc%hashtablesize){
icount++;
uint hashloctmp = hashloc+1;
hashloctmp = hashloctmp%hashtablesize;
printf("%d: hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,hashloctmp,hash[2*hashloctmp],hashkey,hashkey%hash_stride,hashkey/hash_stride);
if (icount > max_collisions_allowed) {
printf("Error -- too many read hash collisions\n");
exit(0);
}
}
read_hash_collisions += icount;
} else {
printf("Error -- Illegal value of hash_report_level %d\n",hash_report_level);
exit(1);
}
} else {
printf("Error -- Illegal value of hash_method %d\n",hash_method);
exit(1);
}
if (hash[2*hashloc] != -1) hashval = hash[2*hashloc+1];
return(hashval);
}