/* Implement a cached obstack.
   Written by Fred Fish <fnf@cygnus.com>
   Rewritten by Jim Blandy <jimb@cygnus.com>

   Copyright (C) 1999, 2000, 2002, 2003, 2007, 2008, 2009, 2010, 2011
   Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "gdb_obstack.h"
#include "bcache.h"
#include "gdb_string.h"		/* For memcpy declaration */
#include "gdb_assert.h"

#include <stddef.h>
#include <stdlib.h>

/* The type used to hold a single bcache string.  The user data is
   stored in d.data.  Since it can be any type, it needs to have the
   same alignment as the most strict alignment of any type on the host
   machine.  I don't know of any really correct way to do this in
   stock ANSI C, so just do it the same way obstack.h does.  */

struct bstring
{
  /* Hash chain.  */
  struct bstring *next;
  /* Assume the data length is no more than 64k.  */
  unsigned short length;
  /* The half hash hack.  This contains the upper 16 bits of the hash
     value and is used as a pre-check when comparing two strings and
     avoids the need to do length or memcmp calls.  It proves to be
     roughly 100% effective.  */
  unsigned short half_hash;

  union
  {
    char data[1];
    double dummy;
  }
  d;
};


/* The structure for a bcache itself.  The bcache is initialized, in
   bcache_xmalloc(), by filling it with zeros and then setting the
   corresponding obstack's malloc() and free() methods.  */

struct bcache
{
  /* All the bstrings are allocated here.  */
  struct obstack cache;

  /* How many hash buckets we're using.  */
  unsigned int num_buckets;
  
  /* Hash buckets.  This table is allocated using malloc, so when we
     grow the table we can return the old table to the system.  */
  struct bstring **bucket;

  /* Statistics.  */
  unsigned long unique_count;	/* number of unique strings */
  long total_count;	/* total number of strings cached, including dups */
  long unique_size;	/* size of unique strings, in bytes */
  long total_size;      /* total number of bytes cached, including dups */
  long structure_size;	/* total size of bcache, including infrastructure */
  /* Number of times that the hash table is expanded and hence
     re-built, and the corresponding number of times that a string is
     [re]hashed as part of entering it into the expanded table.  The
     total number of hashes can be computed by adding TOTAL_COUNT to
     expand_hash_count.  */
  unsigned long expand_count;
  unsigned long expand_hash_count;
  /* Number of times that the half-hash compare hit (compare the upper
     16 bits of hash values) hit, but the corresponding combined
     length/data compare missed.  */
  unsigned long half_hash_miss_count;

  /* Hash function to be used for this bcache object.  */
  unsigned long (*hash_function)(const void *addr, int length);

  /* Compare function to be used for this bcache object.  */
  int (*compare_function)(const void *, const void *, int length);
};

/* The old hash function was stolen from SDBM. This is what DB 3.0
   uses now, and is better than the old one.  */

unsigned long
hash(const void *addr, int length)
{
  return hash_continue (addr, length, 0);
}

/* Continue the calculation of the hash H at the given address.  */

unsigned long
hash_continue (const void *addr, int length, unsigned long h)
{
  const unsigned char *k, *e;

  k = (const unsigned char *)addr;
  e = k+length;
  for (; k< e;++k)
    {
      h *=16777619;
      h ^= *k;
    }
  return (h);
}

/* Growing the bcache's hash table.  */

/* If the average chain length grows beyond this, then we want to
   resize our hash table.  */
#define CHAIN_LENGTH_THRESHOLD (5)

static void
expand_hash_table (struct bcache *bcache)
{
  /* A table of good hash table sizes.  Whenever we grow, we pick the
     next larger size from this table.  sizes[i] is close to 1 << (i+10),
     so we roughly double the table size each time.  After we fall off 
     the end of this table, we just double.  Don't laugh --- there have
     been executables sighted with a gigabyte of debug info.  */
  static unsigned long sizes[] = { 
    1021, 2053, 4099, 8191, 16381, 32771,
    65537, 131071, 262144, 524287, 1048573, 2097143,
    4194301, 8388617, 16777213, 33554467, 67108859, 134217757,
    268435459, 536870923, 1073741827, 2147483659UL
  };
  unsigned int new_num_buckets;
  struct bstring **new_buckets;
  unsigned int i;

  /* Count the stats.  Every unique item needs to be re-hashed and
     re-entered.  */
  bcache->expand_count++;
  bcache->expand_hash_count += bcache->unique_count;

  /* Find the next size.  */
  new_num_buckets = bcache->num_buckets * 2;
  for (i = 0; i < (sizeof (sizes) / sizeof (sizes[0])); i++)
    if (sizes[i] > bcache->num_buckets)
      {
	new_num_buckets = sizes[i];
	break;
      }

  /* Allocate the new table.  */
  {
    size_t new_size = new_num_buckets * sizeof (new_buckets[0]);

    new_buckets = (struct bstring **) xmalloc (new_size);
    memset (new_buckets, 0, new_size);

    bcache->structure_size -= (bcache->num_buckets
			       * sizeof (bcache->bucket[0]));
    bcache->structure_size += new_size;
  }

  /* Rehash all existing strings.  */
  for (i = 0; i < bcache->num_buckets; i++)
    {
      struct bstring *s, *next;

      for (s = bcache->bucket[i]; s; s = next)
	{
	  struct bstring **new_bucket;
	  next = s->next;

	  new_bucket = &new_buckets[(bcache->hash_function (&s->d.data,
							    s->length)
				     % new_num_buckets)];
	  s->next = *new_bucket;
	  *new_bucket = s;
	}
    }

  /* Plug in the new table.  */
  if (bcache->bucket)
    xfree (bcache->bucket);
  bcache->bucket = new_buckets;
  bcache->num_buckets = new_num_buckets;
}


/* Looking up things in the bcache.  */

/* The number of bytes needed to allocate a struct bstring whose data
   is N bytes long.  */
#define BSTRING_SIZE(n) (offsetof (struct bstring, d.data) + (n))

/* Find a copy of the LENGTH bytes at ADDR in BCACHE.  If BCACHE has
   never seen those bytes before, add a copy of them to BCACHE.  In
   either case, return a pointer to BCACHE's copy of that string.  */
const void *
bcache (const void *addr, int length, struct bcache *bcache)
{
  return bcache_full (addr, length, bcache, NULL);
}

/* Find a copy of the LENGTH bytes at ADDR in BCACHE.  If BCACHE has
   never seen those bytes before, add a copy of them to BCACHE.  In
   either case, return a pointer to BCACHE's copy of that string.  If
   optional ADDED is not NULL, return 1 in case of new entry or 0 if
   returning an old entry.  */

const void *
bcache_full (const void *addr, int length, struct bcache *bcache, int *added)
{
  unsigned long full_hash;
  unsigned short half_hash;
  int hash_index;
  struct bstring *s;

  if (added)
    *added = 0;

  /* Lazily initialize the obstack.  This can save quite a bit of
     memory in some cases.  */
  if (bcache->total_count == 0)
    {
      /* We could use obstack_specify_allocation here instead, but
	 gdb_obstack.h specifies the allocation/deallocation
	 functions.  */
      obstack_init (&bcache->cache);
    }

  /* If our average chain length is too high, expand the hash table.  */
  if (bcache->unique_count >= bcache->num_buckets * CHAIN_LENGTH_THRESHOLD)
    expand_hash_table (bcache);

  bcache->total_count++;
  bcache->total_size += length;

  full_hash = bcache->hash_function (addr, length);

  half_hash = (full_hash >> 16);
  hash_index = full_hash % bcache->num_buckets;

  /* Search the hash bucket for a string identical to the caller's.
     As a short-circuit first compare the upper part of each hash
     values.  */
  for (s = bcache->bucket[hash_index]; s; s = s->next)
    {
      if (s->half_hash == half_hash)
	{
	  if (s->length == length
	      && bcache->compare_function (&s->d.data, addr, length))
	    return &s->d.data;
	  else
	    bcache->half_hash_miss_count++;
	}
    }

  /* The user's string isn't in the list.  Insert it after *ps.  */
  {
    struct bstring *new
      = obstack_alloc (&bcache->cache, BSTRING_SIZE (length));

    memcpy (&new->d.data, addr, length);
    new->length = length;
    new->next = bcache->bucket[hash_index];
    new->half_hash = half_hash;
    bcache->bucket[hash_index] = new;

    bcache->unique_count++;
    bcache->unique_size += length;
    bcache->structure_size += BSTRING_SIZE (length);

    if (added)
      *added = 1;

    return &new->d.data;
  }
}


/* Compare the byte string at ADDR1 of lenght LENGHT to the
   string at ADDR2.  Return 1 if they are equal.  */

static int
bcache_compare (const void *addr1, const void *addr2, int length)
{
  return memcmp (addr1, addr2, length) == 0;
}

/* Allocating and freeing bcaches.  */

/* Allocated a bcache.  HASH_FUNCTION and COMPARE_FUNCTION can be used
   to pass in custom hash, and compare functions to be used by this
   bcache.  If HASH_FUNCTION is NULL hash() is used and if
   COMPARE_FUNCTION is NULL memcmp() is used.  */

struct bcache *
bcache_xmalloc (unsigned long (*hash_function)(const void *, int length),
                int (*compare_function)(const void *, 
					const void *, 
					int length))
{
  /* Allocate the bcache pre-zeroed.  */
  struct bcache *b = XCALLOC (1, struct bcache);

  if (hash_function)
    b->hash_function = hash_function;
  else
    b->hash_function = hash;

  if (compare_function)
    b->compare_function = compare_function;
  else
    b->compare_function = bcache_compare;
  return b;
}

/* Free all the storage associated with BCACHE.  */
void
bcache_xfree (struct bcache *bcache)
{
  if (bcache == NULL)
    return;
  /* Only free the obstack if we actually initialized it.  */
  if (bcache->total_count > 0)
    obstack_free (&bcache->cache, 0);
  xfree (bcache->bucket);
  xfree (bcache);
}



/* Printing statistics.  */

static void
print_percentage (int portion, int total)
{
  if (total == 0)
    /* i18n: Like "Percentage of duplicates, by count: (not applicable)".  */
    printf_filtered (_("(not applicable)\n"));
  else
    printf_filtered ("%3d%%\n", (int) (portion * 100.0 / total));
}


/* Print statistics on BCACHE's memory usage and efficacity at
   eliminating duplication.  NAME should describe the kind of data
   BCACHE holds.  Statistics are printed using `printf_filtered' and
   its ilk.  */
void
print_bcache_statistics (struct bcache *c, char *type)
{
  int occupied_buckets;
  int max_chain_length;
  int median_chain_length;
  int max_entry_size;
  int median_entry_size;

  /* Count the number of occupied buckets, tally the various string
     lengths, and measure chain lengths.  */
  {
    unsigned int b;
    int *chain_length = XCALLOC (c->num_buckets + 1, int);
    int *entry_size = XCALLOC (c->unique_count + 1, int);
    int stringi = 0;

    occupied_buckets = 0;

    for (b = 0; b < c->num_buckets; b++)
      {
	struct bstring *s = c->bucket[b];

	chain_length[b] = 0;

	if (s)
	  {
	    occupied_buckets++;
	    
	    while (s)
	      {
		gdb_assert (b < c->num_buckets);
		chain_length[b]++;
		gdb_assert (stringi < c->unique_count);
		entry_size[stringi++] = s->length;
		s = s->next;
	      }
	  }
      }

    /* To compute the median, we need the set of chain lengths
       sorted.  */
    qsort (chain_length, c->num_buckets, sizeof (chain_length[0]),
	   compare_positive_ints);
    qsort (entry_size, c->unique_count, sizeof (entry_size[0]),
	   compare_positive_ints);

    if (c->num_buckets > 0)
      {
	max_chain_length = chain_length[c->num_buckets - 1];
	median_chain_length = chain_length[c->num_buckets / 2];
      }
    else
      {
	max_chain_length = 0;
	median_chain_length = 0;
      }
    if (c->unique_count > 0)
      {
	max_entry_size = entry_size[c->unique_count - 1];
	median_entry_size = entry_size[c->unique_count / 2];
      }
    else
      {
	max_entry_size = 0;
	median_entry_size = 0;
      }

    xfree (chain_length);
    xfree (entry_size);
  }

  printf_filtered (_("  Cached '%s' statistics:\n"), type);
  printf_filtered (_("    Total object count:  %ld\n"), c->total_count);
  printf_filtered (_("    Unique object count: %lu\n"), c->unique_count);
  printf_filtered (_("    Percentage of duplicates, by count: "));
  print_percentage (c->total_count - c->unique_count, c->total_count);
  printf_filtered ("\n");

  printf_filtered (_("    Total object size:   %ld\n"), c->total_size);
  printf_filtered (_("    Unique object size:  %ld\n"), c->unique_size);
  printf_filtered (_("    Percentage of duplicates, by size:  "));
  print_percentage (c->total_size - c->unique_size, c->total_size);
  printf_filtered ("\n");

  printf_filtered (_("    Max entry size:     %d\n"), max_entry_size);
  printf_filtered (_("    Average entry size: "));
  if (c->unique_count > 0)
    printf_filtered ("%ld\n", c->unique_size / c->unique_count);
  else
    /* i18n: "Average entry size: (not applicable)".  */
    printf_filtered (_("(not applicable)\n"));    
  printf_filtered (_("    Median entry size:  %d\n"), median_entry_size);
  printf_filtered ("\n");

  printf_filtered (_("    \
Total memory used by bcache, including overhead: %ld\n"),
		   c->structure_size);
  printf_filtered (_("    Percentage memory overhead: "));
  print_percentage (c->structure_size - c->unique_size, c->unique_size);
  printf_filtered (_("    Net memory savings:         "));
  print_percentage (c->total_size - c->structure_size, c->total_size);
  printf_filtered ("\n");

  printf_filtered (_("    Hash table size:           %3d\n"), 
		   c->num_buckets);
  printf_filtered (_("    Hash table expands:        %lu\n"),
		   c->expand_count);
  printf_filtered (_("    Hash table hashes:         %lu\n"),
		   c->total_count + c->expand_hash_count);
  printf_filtered (_("    Half hash misses:          %lu\n"),
		   c->half_hash_miss_count);
  printf_filtered (_("    Hash table population:     "));
  print_percentage (occupied_buckets, c->num_buckets);
  printf_filtered (_("    Median hash chain length:  %3d\n"),
		   median_chain_length);
  printf_filtered (_("    Average hash chain length: "));
  if (c->num_buckets > 0)
    printf_filtered ("%3lu\n", c->unique_count / c->num_buckets);
  else
    /* i18n: "Average hash chain length: (not applicable)".  */
    printf_filtered (_("(not applicable)\n"));
  printf_filtered (_("    Maximum hash chain length: %3d\n"), 
		   max_chain_length);
  printf_filtered ("\n");
}

int
bcache_memory_used (struct bcache *bcache)
{
  if (bcache->total_count == 0)
    return 0;
  return obstack_memory_used (&bcache->cache);
}
