/* 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 Lesser 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser 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.
 */

/*
 * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
 * file for a list of people on the GLib Team.  See the ChangeLog
 * files for a list of changes.  These files are distributed with
 * GLib at ftp://ftp.gtk.org/pub/gtk/.
 */

/*
 * MT safe
 */

#include "config.h"

#include "gcache.h"

#include "ghash.h"
#include "gtestutils.h"

/**
 * SECTION: caches
 * @title: Caches
 * @short_description: caches allow sharing of complex data structures
 *                     to save resources
 *
 * A #GCache allows sharing of complex data structures, in order to
 * save system resources.
 *
 * GTK+ uses caches for #GtkStyles and #GdkGCs. These consume a lot of
 * resources, so a #GCache is used to see if a #GtkStyle or #GdkGC with
 * the required properties already exists. If it does, then the
 * existing object is used instead of creating a new one.
 *
 * #GCache uses keys and values. A #GCache key describes the properties
 * of a particular resource. A #GCache value is the actual resource.
 **/

typedef struct _GCacheNode  GCacheNode;

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

/**
 * GCache:
 *
 * The #GCache struct is an opaque data structure containing
 * information about a #GCache. It should only be accessed via the
 * following functions.
 **/
struct _GCache
{
  /* 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 inline GCacheNode*
g_cache_node_new (gpointer value)
{
  GCacheNode *node = g_slice_new (GCacheNode);
  node->value = value;
  node->ref_count = 1;
  return node;
}

static inline void
g_cache_node_destroy (GCacheNode *node)
{
  g_slice_free (GCacheNode, node);
}

/**
 * g_cache_new:
 * @value_new_func: a function to create a new object given a key.
 *                  This is called by g_cache_insert() if an object
 *                  with the given key does not already exist.
 * @value_destroy_func: a function to destroy an object. It is called
 *                      by g_cache_remove() when the object is no
 *                      longer needed (i.e. its reference count drops
 *                      to 0).
 * @key_dup_func: a function to copy a key. It is called by
 *                g_cache_insert() if the key does not already exist in
 *                the #GCache.
 * @key_destroy_func: a function to destroy a key. It is called by
 *                    g_cache_remove() when the object is no longer
 *                    needed (i.e. its reference count drops to 0).
 * @hash_key_func: a function to create a hash value from a key.
 * @hash_value_func: a function to create a hash value from a value.
 * @key_equal_func: a function to compare two keys. It should return
 *                  %TRUE if the two keys are equivalent.
 * @Returns: a new #GCache.
 *
 * Creates a new #GCache.
 **/
/**
 * GCacheNewFunc:
 * @key: a #GCache key.
 * @Returns: a new #GCache value corresponding to the key.
 *
 * Specifies the type of the @value_new_func function passed to
 * g_cache_new(). It is passed a #GCache key and should create the
 * value corresponding to the key.
 **/
/**
 * GCacheDestroyFunc:
 * @value: the #GCache value to destroy.
 *
 * Specifies the type of the @value_destroy_func and @key_destroy_func
 * functions passed to g_cache_new(). The functions are passed a
 * pointer to the #GCache key or #GCache value and should free any
 * memory and other resources associated with it.
 **/
/**
 * GCacheDupFunc:
 * @value: the #GCache key to destroy (<emphasis>not</emphasis> a
 *         #GCache value as it seems).
 * @Returns: a copy of the #GCache key.
 *
 * Specifies the type of the @key_dup_func function passed to
 * g_cache_new(). The function is passed a key
 * (<emphasis>not</emphasis> a value as the prototype implies) and
 * should return a duplicate of the key.
 **/
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,
             GEqualFunc         key_equal_func)
{
  GCache *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_equal_func != NULL, NULL);

  cache = g_slice_new (GCache);
  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_equal_func);
  cache->value_table = g_hash_table_new (hash_value_func, NULL);

  return cache;
}

/**
 * g_cache_destroy:
 * @cache: a #GCache.
 *
 * Frees the memory allocated for the #GCache.
 *
 * Note that it does not destroy the keys and values which were
 * contained in the #GCache.
 **/
void
g_cache_destroy (GCache *cache)
{
  g_return_if_fail (cache != NULL);

  g_hash_table_destroy (cache->key_table);
  g_hash_table_destroy (cache->value_table);
  g_slice_free (GCache, cache);
}

/**
 * g_cache_insert:
 * @cache: a #GCache.
 * @key: a key describing a #GCache object.
 * @Returns: a pointer to a #GCache value.
 *
 * Gets the value corresponding to the given key, creating it if
 * necessary. It first checks if the value already exists in the
 * #GCache, by using the @key_equal_func function passed to
 * g_cache_new(). If it does already exist it is returned, and its
 * reference count is increased by one. If the value does not currently
 * exist, if is created by calling the @value_new_func. The key is
 * duplicated by calling @key_dup_func and the duplicated key and value
 * are inserted into the #GCache.
 **/
gpointer
g_cache_insert (GCache   *cache,
                gpointer  key)
{
  GCacheNode *node;
  gpointer value;

  g_return_val_if_fail (cache != NULL, NULL);

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

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

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

  return node->value;
}

/**
 * g_cache_remove:
 * @cache: a #GCache.
 * @value: the value to remove.
 *
 * Decreases the reference count of the given value. If it drops to 0
 * then the value and its corresponding key are destroyed, using the
 * @value_destroy_func and @key_destroy_func passed to g_cache_new().
 **/
void
g_cache_remove (GCache        *cache,
                gconstpointer  value)
{
  GCacheNode *node;
  gpointer key;

  g_return_if_fail (cache != NULL);

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

  g_return_if_fail (node != NULL);

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

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

/**
 * g_cache_key_foreach:
 * @cache: a #GCache.
 * @func: the function to call with each #GCache key.
 * @user_data: user data to pass to the function.
 *
 * Calls the given function for each of the keys in the #GCache.
 *
 * NOTE @func is passed three parameters, the value and key of a cache
 * entry and the @user_data. The order of value and key is different
 * from the order in which g_hash_table_foreach() passes key-value
 * pairs to its callback function !
 **/
void
g_cache_key_foreach (GCache   *cache,
                     GHFunc    func,
                     gpointer  user_data)
{
  g_return_if_fail (cache != NULL);
  g_return_if_fail (func != NULL);

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

/**
 * g_cache_value_foreach:
 * @cache: a #GCache.
 * @func: the function to call with each #GCache value.
 * @user_data: user data to pass to the function.
 *
 * Calls the given function for each of the values in the #GCache.
 *
 * Deprecated:2.10: The reason is that it passes pointers to internal
 *                  data structures to @func; use g_cache_key_foreach()
 *                  instead
 **/
void
g_cache_value_foreach (GCache   *cache,
                       GHFunc    func,
                       gpointer  user_data)
{
  g_return_if_fail (cache != NULL);
  g_return_if_fail (func != NULL);

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