/***************************************************************************
 * Copyright 1995 Michael Veksler. mveksler@vnet.ibm.com
 ***************************************************************************
 * File:      generic_hash.c
 * Purpose :  dynamically growing hash, may use shared or local memory.
 ***************************************************************************
 */
#ifdef CONFIG_IPC

#include <sys/types.h>
#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;
}

#endif  /* CONFIG_IPC */
