/* GLIB - Library of useful routines for C programming
 * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/* 
 * MT safe
 */

#include "glib.h"


typedef struct _GCacheNode  GCacheNode;
typedef struct _GRealCache  GRealCache;

struct _GCacheNode
{
  /* A reference counted node */
  gpointer value;
  gint ref_count;
};

struct _GRealCache
{
  /* Called to create a value from a key */
  GCacheNewFunc value_new_func;

  /* Called to destroy a value */
  GCacheDestroyFunc value_destroy_func;

  /* Called to duplicate a key */
  GCacheDupFunc key_dup_func;

  /* Called to destroy a key */
  GCacheDestroyFunc key_destroy_func;

  /* Associates keys with nodes */
  GHashTable *key_table;

  /* Associates nodes with keys */
  GHashTable *value_table;
};


static GCacheNode* g_cache_node_new     (gpointer value);
static void        g_cache_node_destroy (GCacheNode *node);


static GMemChunk *node_mem_chunk = NULL;
G_LOCK_DEFINE_STATIC (node_mem_chunk);

GCache*
g_cache_new (GCacheNewFunc      value_new_func,
	     GCacheDestroyFunc  value_destroy_func,
	     GCacheDupFunc      key_dup_func,
	     GCacheDestroyFunc  key_destroy_func,
	     GHashFunc          hash_key_func,
	     GHashFunc          hash_value_func,
	     GCompareFunc       key_compare_func)
{
  GRealCache *cache;

  g_return_val_if_fail (value_new_func != NULL, NULL);
  g_return_val_if_fail (value_destroy_func != NULL, NULL);
  g_return_val_if_fail (key_dup_func != NULL, NULL);
  g_return_val_if_fail (key_destroy_func != NULL, NULL);
  g_return_val_if_fail (hash_key_func != NULL, NULL);
  g_return_val_if_fail (hash_value_func != NULL, NULL);
  g_return_val_if_fail (key_compare_func != NULL, NULL);

  cache = g_new (GRealCache, 1);
  cache->value_new_func = value_new_func;
  cache->value_destroy_func = value_destroy_func;
  cache->key_dup_func = key_dup_func;
  cache->key_destroy_func = key_destroy_func;
  cache->key_table = g_hash_table_new (hash_key_func, key_compare_func);
  cache->value_table = g_hash_table_new (hash_value_func, NULL);

  return (GCache*) cache;
}

void
g_cache_destroy (GCache *cache)
{
  GRealCache *rcache;

  g_return_if_fail (cache != NULL);

  rcache = (GRealCache*) cache;
  g_hash_table_destroy (rcache->key_table);
  g_hash_table_destroy (rcache->value_table);
  g_free (rcache);
}

gpointer
g_cache_insert (GCache   *cache,
		gpointer  key)
{
  GRealCache *rcache;
  GCacheNode *node;
  gpointer value;

  g_return_val_if_fail (cache != NULL, NULL);

  rcache = (GRealCache*) cache;

  node = g_hash_table_lookup (rcache->key_table, key);
  if (node)
    {
      node->ref_count += 1;
      return node->value;
    }

  key = (* rcache->key_dup_func) (key);
  value = (* rcache->value_new_func) (key);
  node = g_cache_node_new (value);

  g_hash_table_insert (rcache->key_table, key, node);
  g_hash_table_insert (rcache->value_table, value, key);

  return node->value;
}

void
g_cache_remove (GCache   *cache,
		gpointer  value)
{
  GRealCache *rcache;
  GCacheNode *node;
  gpointer key;

  g_return_if_fail (cache != NULL);

  rcache = (GRealCache*) cache;

  key = g_hash_table_lookup (rcache->value_table, value);
  node = g_hash_table_lookup (rcache->key_table, key);

  node->ref_count -= 1;
  if (node->ref_count == 0)
    {
      g_hash_table_remove (rcache->value_table, value);
      g_hash_table_remove (rcache->key_table, key);

      (* rcache->key_destroy_func) (key);
      (* rcache->value_destroy_func) (node->value);
      g_cache_node_destroy (node);
    }
}

void
g_cache_key_foreach (GCache   *cache,
		     GHFunc    func,
		     gpointer  user_data)
{
  GRealCache *rcache;

  g_return_if_fail (cache != NULL);
  g_return_if_fail (func != NULL);

  rcache = (GRealCache*) cache;

  g_hash_table_foreach (rcache->value_table, func, user_data);
}

void
g_cache_value_foreach (GCache   *cache,
		       GHFunc    func,
		       gpointer  user_data)
{
  GRealCache *rcache;

  g_return_if_fail (cache != NULL);
  g_return_if_fail (func != NULL);

  rcache = (GRealCache*) cache;

  g_hash_table_foreach (rcache->key_table, func, user_data);
}


static GCacheNode*
g_cache_node_new (gpointer value)
{
  GCacheNode *node;

  G_LOCK (node_mem_chunk);
  if (!node_mem_chunk)
    node_mem_chunk = g_mem_chunk_new ("cache node mem chunk", sizeof (GCacheNode),
				      1024, G_ALLOC_AND_FREE);

  node = g_chunk_new (GCacheNode, node_mem_chunk);
  G_UNLOCK (node_mem_chunk);

  node->value = value;
  node->ref_count = 1;

  return node;
}

static void
g_cache_node_destroy (GCacheNode *node)
{
  G_LOCK (node_mem_chunk);
  g_mem_chunk_free (node_mem_chunk, node);
  G_UNLOCK (node_mem_chunk);
}
