#include "otalk.h"
#include <assert.h>

#define DIC_MAX_GLOBALS 2048
#define CACHE_MAX_GLOBALS 1024

static T_OBJECT globals_dictionary_key[DIC_MAX_GLOBALS];
static T_OBJECT globals_dictionary_value[DIC_MAX_GLOBALS];

static int cache[CACHE_MAX_GLOBALS];

int global_cache_hit = 0;
int global_cache_miss = 0;

T_OBJECT global_value_for(T_OBJECT symbol)
{
  int hash_id,i;
  T_OBJECT *array_keys=globals_dictionary_key;

  hash_id = (((unsigned int)(symbol)) >> 4) & (CACHE_MAX_GLOBALS-1);
  /*   printf("Hashid for %s is %d\n",STRING_CHARS(symbol),hash_id); */
  i = cache[hash_id];

  if (globals_dictionary_key[i] == symbol) {
    ++global_cache_hit;
    return globals_dictionary_value[i];
  }
  ++global_cache_miss;
  
  for (i=0; i<DIC_MAX_GLOBALS; ++i,++array_keys) {
    if (symbol == *array_keys) {
      cache[hash_id] = i;
      return globals_dictionary_value[i];
    }
  }

  return VALUE_NIL;
}

void set_global_value_for(T_OBJECT symbol,T_OBJECT value)
{
  int hash_id,i;
  T_OBJECT *array_keys=globals_dictionary_key;
  int first_null = -1;

  hash_id = (((unsigned int)(symbol)) >> 4) & (CACHE_MAX_GLOBALS-1);
  /*   printf("Hashid for %s is %d\n",STRING_CHARS(symbol),hash_id); */
  i = cache[hash_id];

  if (globals_dictionary_key[i] == symbol) {
    globals_dictionary_value[i] = value;
    ++global_cache_hit;
    return;
  }
  ++global_cache_miss;
  
  for (i=0; i<DIC_MAX_GLOBALS; ++i,++array_keys) {
    if (symbol == *array_keys) {
      cache[hash_id] = i;
      globals_dictionary_value[i] = value;
      return;
    } else if ((*array_keys == NULL) &&
	       (first_null == -1)) {
      first_null = i;
    }
  }

  if (first_null == -1) {
    fprintf(stderr,"Kein Platz mehr für globale Variable\n");
    exit(8);
  }

  globals_dictionary_key[first_null] = symbol;
  globals_dictionary_value[first_null] = value;
}


/* eof */

