/***************************************************************************
 * Copyright 1995 Michael Veksler. mveksler@vnet.ibm.com
 ***************************************************************************
 * File:      generic_hash.c
 * Purpose :  dynamically growing hash, may use shared or local memory.
 ***************************************************************************
 */
#include <stdlib.h>
#include <assert.h>
#include "generic_hash.h"

#define ROUND_UP4(num) (( (num)+3) & ~3)

#define FREE_ENTRY          0
#define DELETED_ENTRY       ((DWORD)-1)

#define NO_OF_PRIMES   512
#define GET_ITEM(items,size,i)\
           (*(HASH_ITEM*) \
	    (  ((char *)(items))+ \
	       (i)*(size)) )

static HASH_ITEM *locate_entry(HASH_CONTAINER* hash, DWORD key,
			       HASH_VAL *seeked_data, BOOL skip_deleted);

static void copy_hash_items(HASH_CONTAINER *hash, HASH_ITEM *old_items,
			    int old_n_items);

static BOOL arrays_initialized = FALSE;
static int primes[NO_OF_PRIMES];
static int best_primes[NO_OF_PRIMES];
static int no_of_primes;
static int no_of_best_primes;
static int max_num;

/* binary search for `num' in the `primes' array */
static BOOL prime_binary_search_found(int num)
{
  int min_idx, max_idx, idx;
  
  min_idx=0;
  max_idx=no_of_primes-1;
  
  while (min_idx <= max_idx) {
     idx = (max_idx + min_idx) >> 1;
     if (num == primes[idx])
	return TRUE;
     if (num < primes[idx])
	max_idx = idx-1;
     else
	min_idx = idx+1;
  }
  return FALSE;
}

static BOOL is_prime(int num)
{
  int i;
  if ((num & 0x1) == 0)		   /* can be divided by 2 */
     if (num == 2) 
	return TRUE;
     else
	return FALSE;
  
  if (num <= primes[no_of_primes-1]) 
     return prime_binary_search_found(num);

  for (i=0 ; i < no_of_primes ; i++) {
     if (num % primes[i] == 0)
	return FALSE;
     if (num < primes[i] * primes[i])
	return TRUE;
  }
  return TRUE;
}

static void setup_primes()
{
  int num;
  
  primes[0]=2;
  primes[1]=3;
  no_of_primes=2;
  
  /* count in modulo 6 to avoid numbers that divide by 2 or 3 */
  for (num=5 ; ; num+=6) {
     if (is_prime(num)) {
	primes[no_of_primes++]=num;
	if (no_of_primes >= NO_OF_PRIMES)
	   break;
     }
     if (is_prime(num+2)) {
	primes[no_of_primes++]=num+2;
	if (no_of_primes >= NO_OF_PRIMES)
	   break;
     }
  }
  max_num= primes[no_of_primes-1] * primes[no_of_primes-1];
}


/* Find primes which are far "enough" from powers of two */

void setup_best_primes()
{
  int i;
  int num;
  int pow2before, pow2after;
  int min_range, max_range;

  min_range=3;
  max_range=3;
  pow2before= 2;
  pow2after= 4;

  no_of_best_primes= 0;
  for (i=0 ; i < no_of_primes ; i++){
     num= primes[i];

     if (num > pow2after) {
	pow2before= pow2after;
	pow2after <<=1;
	min_range= pow2before+ (pow2before >> 3);
	max_range= pow2after-  (pow2before >> 2);
     }
     if (num > min_range && num < max_range) 
	best_primes[no_of_best_primes++]=num;
  }
}

/* binary search for `num' in the `best_primes' array,
 * Return smallest best_prime >= num.
 */
static int best_prime_binary_search(int num)
{
  int min_idx, max_idx, idx;
  
  min_idx=0;
  max_idx=no_of_best_primes-1;
  
  while (1) {
     idx = (max_idx + min_idx) >> 1;
     if (num == best_primes[idx])
	return num;
     if (num < best_primes[idx]) {
	max_idx = idx-1;
	if (max_idx <= min_idx)
	    return best_primes[idx];
    }
     else {
	min_idx = idx+1;
	if (min_idx >= max_idx)
	    return best_primes[max_idx];
    }
  }

}

/* Find the best prime, near `num' (which can be any number) */
static int best_prime(int num)
{
  int log2;
  int pow2less, pow2more;
  int min_range, max_range;

  if (num < 11)
     return 11;
  
  if (num <= best_primes[no_of_best_primes-1])
     return best_prime_binary_search(num);

  assert( num < max_num );

  for (log2=0 ; num >> log2 ; log2++)
     ;

  pow2less= 1 << log2;
  pow2more= 1 << (log2+1);
  min_range= pow2less + (pow2less >> 3);
  max_range= pow2more - (pow2more >> 3);

  if (num < min_range)
     num= min_range;

  num |= 1;			   /* make sure num can't be divided by 2 */
  
  while (1) {
     if (num >= max_range) {
	pow2less<<= 1;
	pow2more<<= 1;
	min_range= pow2less + (pow2less >> 3);
	max_range= pow2more - (pow2more >> 3);
	num= min_range | 1;	   /* make sure num can't be divided by 2 */
     }
     /* num should be here in the range: (min_range, max_range) */
     if (is_prime(num))
	return num;
     num+=2;
  }
}

/* FIXME: This can be done before compiling. (uning a script)*/
static void setup_arrays()
{
  setup_primes();
  setup_best_primes();
}

/* Discard all DELETED_ENTRYs moving the data to it's correct location.
 * Done without a temporary buffer.
 * May require some efficiency improvements ( currently it's o(N^2)
 * or is it o(N^3) in the worst case ? In the avarege it seems to be
 * something like o(N log (N)))
 */
static void static_collect_garbge(HASH_CONTAINER *hash)
{
   int i;
   BOOL change;
   HASH_ITEM *items;
   HASH_ITEM *located;
   HASH_ITEM *item;
   int key;
  
   items= hash->items;
   
   do {
      change= FALSE;
      for (i=hash->shared->total_items-1 ; i >= 0 ; i--) {
	 item= &GET_ITEM(items,hash->bytes_per_item,i);
	 key= item->key;
	 if (key != DELETED_ENTRY && key != FREE_ENTRY) {
	    /* try to place the entry in a deleted location */
	    located= locate_entry(hash, key, &item->data,
				  0 /* no skip_deleted */);
	    if (located->key == DELETED_ENTRY) {
	       change= TRUE;
	       memcpy(&located, &item,
		      hash->bytes_per_item);
	       item->key= DELETED_ENTRY;
	    }
	 }
      }
   } while (change);

   /* No change means that there is no need to go through a DELETED_ENTRY
    * in order to reach an item, so DELETED_ENTRY looses it's special
    * meaning, and it is the same as FREE_ENTRY.
    */
   for (i=hash->shared->total_items-1 ; i >= 0 ; i--)
      if (GET_ITEM(items,hash->bytes_per_item,i).key == DELETED_ENTRY)
	 GET_ITEM(items,hash->bytes_per_item,i).key = FREE_ENTRY;
   hash->shared->deleted_items=0;
}

static void collect_garbge(HASH_CONTAINER *hash)
{
   HASH_SHARED *shared= hash->shared;
   HASH_ITEM *temp_items;
   int size;
    
   size= shared->total_items * hash->bytes_per_item;
   temp_items= (HASH_ITEM*)malloc(size);
   if (temp_items==NULL) {
      static_collect_garbge(hash);
   } else {
      memcpy(temp_items, hash->items, size);
      copy_hash_items(hash, temp_items, shared->total_items);
   }
}


static void copy_hash_items(HASH_CONTAINER *hash, HASH_ITEM *old_items,
			    int old_n_items)
{
   HASH_SHARED *shared= hash->shared;
   HASH_ITEM *item;
   int i;
   
   shared->deleted_items = 0;
   shared->free_items= shared->total_items;
   
   /* make all items free */
   for (i= shared->total_items-1 ; i>=0 ; i--)
      GET_ITEM(hash->items, hash->bytes_per_item, i).key = FREE_ENTRY;
   
   /* copy items */
   for (i=0 ; i <= old_n_items; i++) {
      item= &GET_ITEM(old_items, hash->bytes_per_item,i);
      if (item->key != FREE_ENTRY && item->key != DELETED_ENTRY)
	 hash_add_item(hash, item->key, &item->data);
   } 
}


static void reorder_hash(HASH_CONTAINER *hash)
{
  HASH_SHARED *shared= hash->shared;
  HASH_ITEM *items, *old_items;
  HASH_PTR shared_items, old_shared_items;
  int n_items, old_n_items;
  int size;

  if (shared->deleted_items > hash->min_free_items) {
     collect_garbge(hash);
     return;
  }
  n_items= best_prime(shared->total_items * HASH_REALLOC_JUMPS);

  size= n_items *
	(sizeof(items[0]) - sizeof(items[0].data) + hash->bytes_per_item);
 
  shared_items= hash->allocate_mem(size);
  items= hash->access_mem(shared_items);
  
  if (items == NULL) {
	collect_garbge(hash);
	return;
  }
  old_shared_items = shared->items;
  old_n_items=       shared->total_items;
  old_items=         hash->items;

  /* setup a new clean hash based on the parameters of the original one */
  hash->items=          items;
  shared->total_items = n_items;
  shared->items=        shared_items;
  set_hash_parameters(hash, hash->maximum_load);
  copy_hash_items(hash, old_items, old_n_items);
  
  hash->free_mem(old_shared_items);
  hash->last_ptr_update= ++shared->ptr_updates;
}

/* low level: attach hash existing hash items, no checks are performed
 * No complex calculations done.
 */
static HASH_CONTAINER *attach_no_check(HASH_ITEM *items, int bytes_per_datum)
{
    HASH_CONTAINER *hash;
    int bytes_per_item;
    HASH_ITEM dummy_item;
    
    hash= (HASH_CONTAINER*) malloc(sizeof(HASH_CONTAINER) );
    if (hash == NULL)
	return NULL;
    
    bytes_per_item= bytes_per_datum+
                    sizeof(dummy_item)-sizeof(dummy_item.data);
    hash->bytes_per_item= ROUND_UP4(bytes_per_item);
    hash->items=          items;
    hash->is_correct_item= NULL;
    hash->allocate_mem=   HASH_MEM_ALLOC;
    hash->access_mem=     HASH_MEM_ACCESS;
    hash->free_mem=       HASH_MEM_FREE;
    set_hash_parameters(hash, HASH_LOAD);
    

    return hash;
}


/* Attach existing & running remote (i.e. shared) hash.
 * Attach the items using the data stored in "shared"
 */
HASH_CONTAINER *attach_remote_hash(HASH_SHARED *shared, int bytes_per_datum,
				   HASH_ITEM *(*access_mem)(HASH_PTR))
{
    HASH_CONTAINER *hash;
    HASH_ITEM *items;

    assert(access_mem != NULL);
    if (! arrays_initialized)
	setup_arrays();

    items=access_mem(shared->items);
    hash= attach_no_check(items, bytes_per_datum);
    if (hash == NULL)
	return NULL;
    
    hash->shared_was_malloced = FALSE;
    hash->shared= shared;
    return (hash);
}


HASH_CONTAINER *create_remote_hash(HASH_SHARED *shared,
				   int bytes_per_datum,
				   int total_items,
				   HASH_PTR (*allocate_mem)(int size),
				   HASH_ITEM *(*access_mem)(HASH_PTR))
{
   HASH_CONTAINER *hash;
   int size;
   int i;
    
   assert(total_items >= 1);
   assert(bytes_per_datum >=1);
   assert(access_mem != NULL);
   assert(allocate_mem != NULL);
   assert(shared != NULL);
   if (! arrays_initialized)
      setup_arrays();

   if (total_items < MIN_HASH)
      total_items= MIN_HASH;
   else 
      total_items= best_prime(total_items);

   hash= attach_no_check(NULL, bytes_per_datum);
    
   if (hash==NULL) {
      free(hash);
      return NULL;
   }
    
   shared->total_items=  total_items;
   hash->shared= shared;
   hash->shared_was_malloced = FALSE;

   size= total_items * hash->bytes_per_item;

   shared->items = allocate_mem(size);
   hash->items=    access_mem(shared->items);
    
   if (hash->items == NULL ) {
      free(hash);
      return NULL;
   }
   shared->items.ptr= hash->items;
    
   /* make all items free */
   for (i=0 ; i < total_items ; i++)
      GET_ITEM(hash->items,hash->bytes_per_item,i).key = FREE_ENTRY;
    
   shared->deleted_items= 0;
   shared->free_items= total_items;
   shared->ptr_updates= 0;
   return hash;

}

/* hash constructor: create brand new hash */
HASH_CONTAINER *create_hash(int bytes_per_datum, int total_items)
{
   HASH_CONTAINER *hash;
   HASH_SHARED *shared;

   
   shared= (HASH_SHARED*)malloc(sizeof(HASH_SHARED));
   if (shared == NULL)
      return NULL;
   
   hash= create_remote_hash(shared, bytes_per_datum, total_items,
			    HASH_MEM_ALLOC, HASH_MEM_ACCESS);

   if (hash == NULL) {
      free(shared);
      return NULL;
   }
   
   hash->shared_was_malloced = TRUE;
   return hash;
}

/* set the extra handlers to non default values */
void set_hash_handlers(HASH_CONTAINER *hash,
		       HASH_ITEM_TEST *is_correct_item,
		       HASH_PTR (*allocate_mem)(int size),
		       void     (*free_mem)(HASH_PTR),
		       HASH_ITEM *(*access_mem)(HASH_PTR))
{
   assert(hash);
   assert(allocate_mem);
   assert(free_mem);
    
   hash->free_mem     = free_mem;
   hash->allocate_mem = allocate_mem;
   hash->access_mem   = access_mem;
   hash->is_correct_item = is_correct_item;
}


/* set extra parameters */
void set_hash_parameters(HASH_CONTAINER *hash, int load)
{
   assert(hash);
   assert(load>30);		/* no sence to realloc with less than */
				/* 50% load, limiting to 30% to be on */
				/* the safe size */
   assert(load<=100);
    
   hash->maximum_load=   load;
   hash->min_free_items= (1.0 - load/100.0) * hash->shared->total_items + 1 ;
}

/* hash destructor: destroy anything related to the hash */
void destroy_hash(HASH_CONTAINER *hash)
{
   assert(hash);
   hash->free_mem(hash->shared->items);
   if (hash->shared_was_malloced)
      free(hash->shared);
   free(hash);
}

/* hash destructor: just detach hash, without destroing it (makes */
/* sence in shared memory environment) */
void detach_hash(HASH_CONTAINER *hash)
{
   assert(hash);
   free(hash);
}


/********** Hash usage *************/
static __inline__ BOOL
correct_entry(HASH_ITEM *item, int key, HASH_VAL *seeked_data,
	      HASH_ITEM_TEST *is_correct_item, BOOL skip_deleted)
{
   switch(item->key) {
      case FREE_ENTRY:
	 return TRUE;
	
      case DELETED_ENTRY:
	 return skip_deleted ? FALSE : TRUE;
	
      default:
	 if (item->key != key)
	    return FALSE;
	 if (is_correct_item != NULL)
	    return is_correct_item(&item->data, seeked_data);
	 else 
	    return TRUE;
   }

}

/* The algorithm of the hash (one of the 2 standard hash implementations):
 *   Iterate through the hash table until
 *    1. The entry has been found.
 *    2. A FREE entry has been found.
 *    3. For insert operations only- A DELETED entry has been found.
 *       The difference between DELETED and FREE entires is that
 *       DELETED entry was one occupied, while FREE was never allocated.
 *       The idea behind this structure to keep other entries reachable.
 */

static HASH_ITEM *locate_entry(HASH_CONTAINER* hash, DWORD key,
			       HASH_VAL *seeked_data, BOOL skip_deleted)
{
   DWORD hash_idx, hash_leaps;
   HASH_ITEM *item;
   int i;
   int total_items;
    
   assert(hash);

   total_items=     hash->shared->total_items;
   hash_idx=        key % total_items;
   
   item= &GET_ITEM(hash->items, hash->bytes_per_item, hash_idx);
    
   if (  correct_entry( item, key, seeked_data,
			hash->is_correct_item, skip_deleted)   )
      return item;

   /* get the WORDs in different order in this DWORD to avoid clustering */
   hash_leaps=((DWORD)MAKELONG(HIWORD(key), LOWORD(key))
	       % (total_items-1)) +1;

   /* interate through the hash table using hash_leaps */
   for (i= total_items ; i ; i--) {
      hash_idx+= hash_leaps;
      if (hash_idx > total_items)
	 hash_idx -= total_items;
	
      item= &GET_ITEM(hash->items,hash->bytes_per_item, hash_idx);
      if (  correct_entry( item, key, seeked_data,
			   hash->is_correct_item, skip_deleted)   )
	 return item;
   }
   return NULL;
    
}

static __inline__ void sync_shared_hash(HASH_CONTAINER *hash)
{
    HASH_SHARED *shared= hash->shared;
    
    if (shared->ptr_updates == hash->last_ptr_update)
	return;
    
    assert(shared->ptr_updates >= hash->last_ptr_update);
    hash->last_ptr_update= shared->ptr_updates;
    hash->min_free_items= (1.0 - hash->maximum_load/100.0) *
	shared->total_items + 1 ;

    hash->items= hash->access_mem(shared->items);
}

HASH_VAL *hash_locate_item(HASH_CONTAINER* hash,
			   int key, HASH_VAL *seeked_data)
{
    HASH_ITEM *item;
    
    assert(hash != NULL);
    sync_shared_hash(hash);
    
    item= locate_entry(hash, key, seeked_data, 1 /* skip_deleted */);
    if (item == NULL)
	return NULL;
    if (item->key == FREE_ENTRY )
	return NULL;

    return &item->data;
}


BOOL hash_add_item(HASH_CONTAINER* hash, int key, HASH_VAL *data)
{
    HASH_SHARED *shared;
    HASH_ITEM *item;
    
    assert(hash != NULL);

    sync_shared_hash(hash);
    shared= hash->shared;
    
    item=locate_entry(hash, key, data, 0 /* no skip_deleted */);
    assert(item != NULL);
    if (item->key == key)
	return FALSE;
    if (item->key == FREE_ENTRY)
       shared->free_items--;
    else
       shared->deleted_items--;
    
    item->key=  key;
    memcpy(&item->data, data, hash->bytes_per_item-sizeof(key));

    if (shared->free_items < hash->min_free_items ||
	shared->deleted_items > hash->min_free_items)
       reorder_hash(hash);
    
    return TRUE;
}


BOOL hash_delete_item(HASH_CONTAINER* hash, int key, HASH_VAL *seeked_data)
{
    HASH_ITEM *item;
    
    assert(hash != NULL);
    sync_shared_hash(hash);

    item=locate_entry(hash, key, seeked_data, 1 /* skip_deleted */);
    if (item == NULL)
	return FALSE;

    if (item->key == FREE_ENTRY) 
	return FALSE;

    item->key = DELETED_ENTRY;
    hash->shared->deleted_items++;

    return TRUE;
}

void *ret_null()
{
    return NULL;
}


HASH_ITEM *access_local_hash(HASH_PTR ptr)
{
   return ptr.ptr;
}
