/* Copyright (C) 2012-2021 Free Software Foundation, Inc.

   This file is part of GCC.

   GCC 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, or (at your option)
   any later version.

   GCC 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.

   Under Section 7 of GPL version 3, you are granted additional
   permissions described in the GCC Runtime Library Exception, version
   3.1, as published by the Free Software Foundation.

   You should have received a copy of the GNU General Public License
   and a copy of the GCC Runtime Library Exception along with this
   program; see the files COPYING3 and COPYING.RUNTIME respectively.
   If not, see <http://www.gnu.org/licenses/>.  */

#ifndef _VTV_SET_H
#define _VTV_SET_H 1

/* Code in this file manages a collection of insert-only sets.  We
   have only tested the case where Key is uintptr_t, though it
   theoretically should work for some other cases.  All odd keys are
   reserved, and must not be inserted into any of the sets.  This code
   is intended primarily for sets of pointers, and the code is
   optimized for small sets (including size 0 and 1), but regardless
   of the set size, insert() and contains() have close to O(1) speed
   in practice.

   TODO(gpike): fix this comment.

   Recommended multithreaded use of a set:

   For speed, we want to use a lock-free test for set membership.  The
   code handles simultaneous reads and inserts, as long as at most one
   insertion is in progress at a time.  After an insert, other threads
   may not immediately "see" the inserted key if they perform a
   lock-free read, so we recommend retrying, as explained below.

   Also, to make data corruption less likely, we recommend using a
   "normal" RW page as well as one or pages that are typically RO
   but that can be switched to RW and back as needed.  The latter
   pages should contain sets.  The former should contain a lock, L,
   and an int or similar, num_writers.  Then, to insert, something
   like this would be safe:
    o Acquire L.
    o Increment num_writers; if that made it 1, change pages to RW.
    o Release L.
    o while (there are insertions to do in some set, S) {
        acquire L;
        do some insertions in S;
        release L;
      }
    o Acquire L.
    o Decrement num_writers; if that made it 0, change pages to RO.
    o Release L.

   And to check if the set contains some key, one could use
     set.contains(key) ||
       ({ Acquire L; bool b = set.contains(key); Release L; b; })

   In this scheme, the number of threads with reads in progress isn't
   tracked, so old sets can never be deleted.  In addition, on some
   architectures the intentionally racy reads might cause contains()
   to return true when it should have returned false.  This should be
   no problem on x86, and most other machines, where reading or
   writing an aligned uintptr_t is atomic.  E.g., on those machines,
   if *p is 0 and one thread does *p = x while another reads *p, the
   read will see either 0 or x.

   To make the above easier, the insert_only_hash_sets class provides
   an interface to manipulate any number of hash sets.  One shouldn't
   create objects of that class, as it has no member data and its
   methods are static.

   So the recommended model is to have a single lock, a single
   num_writers variable, and some number of sets.  If lock contention
   becomes a problem then the sets can be divided into k groups, each
   of which has a lock and a num_writers variable; or each set can be
   represented as a set of values that equal 0 mod m, a set of values
   that equal 1 mod m, ..., plus a set of values that equal m-1 mod m.

   However, we expect most or all uses of this code to call contains()
   much more frequently than anything else, so lock contention is
   likely to be low.  */

#include <algorithm>

#ifndef HASHTABLE_STATS
#define HASHTABLE_STATS 0
#endif

#ifndef HASHTABLE_STATS_ATOMIC
#define HASHTABLE_STATS_ATOMIC 0
#endif

#if HASHTABLE_STATS
#if HASHTABLE_STATS_ATOMIC
/* Stat counters, with atomics. */
#include <bits/atomic_word.h>

typedef _Atomic_word _AtomicStatCounter;

void
inc_by (_AtomicStatCounter &stat, int amount)
{ 
  __atomic_add_fetch (&stat, amount,  __ATOMIC_ACQ_REL);
}

#else

/* Stat counters, but without atomics. */
typedef int _AtomicStatCounter;

void
inc_by (_AtomicStatCounter& stat, int amount)
{ 
  stat += amount;
}

#endif


/* Number of calls to contains(), insert(), etc. */
extern _AtomicStatCounter stat_insert;
extern _AtomicStatCounter stat_contains;
extern _AtomicStatCounter stat_resize;
extern _AtomicStatCounter stat_create;

/* Sum of set size over all calls to contains().  */
extern _AtomicStatCounter stat_contains_sizes;

/* contains() calls in a set whose capacity is more than 1. */
extern _AtomicStatCounter stat_contains_in_non_trivial_set;

/* Probes in a set whose capacity is more than 1.  Ideally, this will
   be pretty close to stat_contains_in_non_trivial_set.  That will
   happen if our hash function is good and/or important keys were
   inserted before unimportant keys.  */
extern _AtomicStatCounter stat_probes_in_non_trivial_set;

/* number of calls to contains() with size=0, 1, etc. */
extern _AtomicStatCounter stat_contains_size0;
extern _AtomicStatCounter stat_contains_size1;
extern _AtomicStatCounter stat_contains_size2;
extern _AtomicStatCounter stat_contains_size3;
extern _AtomicStatCounter stat_contains_size4;
extern _AtomicStatCounter stat_contains_size5;
extern _AtomicStatCounter stat_contains_size6;
extern _AtomicStatCounter stat_contains_size7;
extern _AtomicStatCounter stat_contains_size8;
extern _AtomicStatCounter stat_contains_size9;
extern _AtomicStatCounter stat_contains_size10;
extern _AtomicStatCounter stat_contains_size11;
extern _AtomicStatCounter stat_contains_size12;
extern _AtomicStatCounter stat_contains_size13_or_more;
extern _AtomicStatCounter stat_grow_from_size0_to_1;
extern _AtomicStatCounter stat_grow_from_size1_to_2;
extern _AtomicStatCounter stat_double_the_number_of_buckets;
extern _AtomicStatCounter stat_insert_key_that_was_already_present;

/* Hash collisions detected during insert_no_resize().  Only counts
   hasher(k) == hasher(k'); hasher(k) % tablesize == hasher(k') %
   tablesize is not sufficient.  Will count collisions that are
   detected during table resizes etc., so the same two keys may add to
   this stat multiple times.  */
extern _AtomicStatCounter stat_insert_found_hash_collision;

#include <string>

struct insert_only_hash_sets_logger
{
  static char *
  log (char c, char *buf)
  {
    *buf++ = c;
    return buf;
  }

  static char *
  log (const char *s, char *buf)
  { return strcpy (buf, s) + strlen (s); }

  static char *
  log (_AtomicStatCounter i, char *buf)
  {
    if (i < 10)
      return log ((char) ('0' + i), buf);
    else
      return log ((char) ('0' + i % 10), log (i / 10, buf));
  }

  static char *
  log (const char *label, _AtomicStatCounter i, char *buf)
  {
    buf = log (label, buf);
    buf = log (": ", buf);
    buf = log (i, buf);
    return log ('\n', buf);
  }
};

// Write stats to the given buffer, which should be at least 4000 bytes.
static inline void
insert_only_hash_tables_stats (char *buf)
{
  buf = insert_only_hash_sets_logger::log ("insert", stat_insert, buf);
  buf = insert_only_hash_sets_logger::log ("contains", stat_contains, buf);
  buf = insert_only_hash_sets_logger::log ("resize", stat_resize, buf);
  buf = insert_only_hash_sets_logger::log ("create", stat_create, buf);
  buf = insert_only_hash_sets_logger::log ("insert_key_that_was_already_"
				      "present",
				      stat_insert_key_that_was_already_present,
				      buf);
  buf = insert_only_hash_sets_logger::log ("contains_sizes",
					   stat_contains_sizes, buf);
  buf = insert_only_hash_sets_logger::log ("contains_in_non_trivial_set",
					   stat_contains_in_non_trivial_set,
					   buf);
  buf = insert_only_hash_sets_logger::log ("probes_in_non_trivial_set",
					   stat_probes_in_non_trivial_set,
					   buf);
  buf = insert_only_hash_sets_logger::log ("contains_size0",
					   stat_contains_size0, buf);
  buf = insert_only_hash_sets_logger::log ("contains_size1",
					   stat_contains_size1, buf);
  buf = insert_only_hash_sets_logger::log ("contains_size2",
					   stat_contains_size2, buf);
  buf = insert_only_hash_sets_logger::log ("contains_size3",
					   stat_contains_size3, buf);
  buf = insert_only_hash_sets_logger::log ("contains_size4",
					   stat_contains_size4, buf);
  buf = insert_only_hash_sets_logger::log ("contains_size5",
					   stat_contains_size5, buf);
  buf = insert_only_hash_sets_logger::log ("contains_size6",
					   stat_contains_size6, buf);
  buf = insert_only_hash_sets_logger::log ("contains_size7",
					   stat_contains_size7, buf);
  buf = insert_only_hash_sets_logger::log ("contains_size8",
					   stat_contains_size8, buf);
  buf = insert_only_hash_sets_logger::log ("contains_size9",
					   stat_contains_size9, buf);
  buf = insert_only_hash_sets_logger::log ("contains_size10",
					   stat_contains_size10, buf);
  buf = insert_only_hash_sets_logger::log ("contains_size11",
					   stat_contains_size11, buf);
  buf = insert_only_hash_sets_logger::log ("contains_size12",
					   stat_contains_size12, buf);
  buf = insert_only_hash_sets_logger::log ("contains_size13_or_more",
					   stat_contains_size13_or_more, buf);
  buf = insert_only_hash_sets_logger::log ("grow_from_size0_to_1",
					   stat_grow_from_size0_to_1, buf);
  buf = insert_only_hash_sets_logger::log ("grow_from_size1_to_2",
					   stat_grow_from_size1_to_2, buf);
  buf = insert_only_hash_sets_logger::log ("insert_found_hash_collision",
					   stat_insert_found_hash_collision,
					   buf);
  buf = insert_only_hash_sets_logger::log ("double_the_number_of_buckets",
					   stat_double_the_number_of_buckets,
					   buf);
  *buf = '\0';
}

#else

/* No stats. */
#define inc_by(statname, amount) do { } while (false && (amount))

#endif

#define inc(statname) inc_by (statname, 1)

template <typename Key, class HashFcn, class Alloc>
class insert_only_hash_sets
{
 public:
  typedef Key key_type;
  typedef size_t size_type;
  typedef Alloc alloc_type;
  enum { illegal_key = 1 };
  enum { min_capacity = 4 };
#if HASHTABLE_STATS
  enum { stats = true };
#else
  enum { stats = false };
#endif

  /* Do not directly use insert_only_hash_set.  Instead, use the
     static methods below to create and manipulate objects of the
     following class.
  
     Implementation details: each set is represented by a pointer
     plus, perhaps, out-of-line data, which would be an object of type
     insert_only_hash_set.  For a pointer, s, the interpretation is: s
     == NULL means empty set, lsb(s) == 1 means a set with one
     element, which is (uintptr_t)s - 1, and otherwise s is a pointer
     of type insert_only_hash_set*.  So, to increase the size of a set
     we have to change s and/or *s.  To check if a set contains some
     key we have to examine s and possibly *s.  */
  class insert_only_hash_set
  {
   public:
    /* Insert a key.  The key must not be a reserved key.  */
    static inline insert_only_hash_set *insert (key_type key,
						insert_only_hash_set *s);
    

    /* Create an empty set.  */
    static inline insert_only_hash_set *create (size_type capacity);

    /* Return whether the given key is present.  If key is illegal_key
       then either true or false may be returned, but for all other
       reserved keys false will be returned.  */
    static bool
    contains (key_type key, const insert_only_hash_set *s)
    {
      if (stats)
	{
	  inc (stat_contains);
	  switch (size (s))
	    {
	      case 0: inc (stat_contains_size0); break;
	      case 1: inc (stat_contains_size1); break;
	      case 2: inc (stat_contains_size2); break;
	      case 3: inc (stat_contains_size3); break;
	      case 4: inc (stat_contains_size4); break;
	      case 5: inc (stat_contains_size5); break;
	      case 6: inc (stat_contains_size6); break;
	      case 7: inc (stat_contains_size7); break;
	      case 8: inc (stat_contains_size8); break;
	      case 9: inc (stat_contains_size9); break;
	      case 10: inc (stat_contains_size10); break;
	      case 11: inc (stat_contains_size11); break;
	      case 12: inc (stat_contains_size12); break;
	      default: inc (stat_contains_size13_or_more); break;
	    }
          inc_by (stat_contains_sizes, size (s));
	}

      return (singleton (s) ?
              singleton_key (key) == s :
              ((s != NULL) && s->contains (key)));
    }

    /* Return a set's size.  */
    static size_type
    size (const insert_only_hash_set *s)
    { return (s == NULL) ? 0 : (singleton (s) ? 1 : s->num_entries); }

    static inline insert_only_hash_set *resize (size_type target_num_buckets,
						insert_only_hash_set *s);
    

   private:
    /* Return whether a set has size 1. */
    static bool
    singleton (const insert_only_hash_set *s)
    { return (uintptr_t) s & 1; }

    /* Return the representation of a singleton set containing the
       given key.  */
    static insert_only_hash_set *
    singleton_key (key_type key)
    { return (insert_only_hash_set *) ((uintptr_t) key + 1); }

    /* Given a singleton set, what key does it contain?  */
    static key_type
    extract_singleton_key (const insert_only_hash_set *s)
    {
      VTV_DEBUG_ASSERT (singleton (s));
      return (key_type) ((uintptr_t) s - 1);
    }

    volatile key_type &
    key_at_index (size_type index)
    { return buckets[index]; }

    key_type
    key_at_index (size_type index) const
    { return buckets[index]; }

    size_type
    next_index (size_type index, size_type indices_examined) const
    { return (index + indices_examined) & (num_buckets - 1); }

    inline void insert_no_resize (key_type key);
    
    inline bool contains (key_type key) const;
    
    inline insert_only_hash_set *resize_if_necessary (void);
    
    size_type num_buckets;  /* Must be a power of 2 not less than
			       min_capacity.  */
    volatile size_type num_entries;
    volatile key_type buckets[0];  /* Actual array size is num_buckets.  */
  };

  /* Create an empty set with the given capacity.  Requires that n be
     0 or a power of 2.  If 1 < n < min_capacity then treat n as
     min_capacity.  Sets *handle.  Returns true unless the allocator
     fails.  Subsequent operations on this set should use the same
     handle. */

  static inline bool create (size_type n, insert_only_hash_set **handle);

  /* Force the capacity of a set to be n, unless it was more than n
     already.  Requires that n be 0 or a power of 2.  Sets *handle
     unless the current capacity is n or more.  Returns true unless
     the allocator fails.  */

  static inline bool resize (size_type n, insert_only_hash_set **handle);

  /* Insert a key.  *handle is unmodified unless (1) a resize occurs,
     or (2) the set was initially empty. Returns true unless the
     allocator fails during a resize.  If the allocator fails during a
     resize then the set is reset to be the empty set.  The key must
     not be a reserved key.  */

  static inline bool insert (key_type key, insert_only_hash_set **handle);

  /* Check for the presence of a key.  If key is illegal_key then
     either true or false may be returned, but for all other reserved
     keys false will be returned.  */

  static inline bool
  contains (key_type key, /* const */ insert_only_hash_set **handle)
  { return insert_only_hash_set::contains (key, *handle); }

  /* Return the size of the given set.  */
  static size_type
  size (const insert_only_hash_set **handle)
  { return insert_only_hash_set::size (*handle); }

  static bool
  is_reserved_key (key_type key)
  { return ((uintptr_t) key % 2) == 1; }
};

template <typename Key, class HashFcn, class Alloc>
typename insert_only_hash_sets <Key, HashFcn, Alloc>::insert_only_hash_set *
insert_only_hash_sets <Key, HashFcn, Alloc>::insert_only_hash_set::resize
                                         (size_type n, insert_only_hash_set *s)
{
  if (s == NULL)
    return create (n);

  size_type capacity = singleton (s) ? 1 : s->num_buckets;

  if (n <= capacity)
    return s;

  insert_only_hash_set *result =
                                create (std::max<size_type> (n, min_capacity));
  if (result != NULL)
    {
      if (singleton (s))
        {
          result->insert_no_resize (extract_singleton_key (s));
        }
      else
        {
          for (size_type i = 0; i < s->num_buckets; i++)
            if (s->buckets[i] != (key_type) illegal_key)
              result->insert_no_resize (s->buckets[i]);
        }
      VTV_DEBUG_ASSERT (size (result) == size (s));
    }
  return result;
}

template <typename Key, class HashFcn, class Alloc>
typename insert_only_hash_sets <Key, HashFcn, Alloc>::insert_only_hash_set *
insert_only_hash_sets <Key, HashFcn, Alloc>::insert_only_hash_set::insert 
                                        (key_type key, insert_only_hash_set *s)
{
  VTV_DEBUG_ASSERT (!is_reserved_key (key));

  inc_by (stat_grow_from_size0_to_1, s == NULL);

  if (s == NULL)
    return singleton_key (key);

  if (singleton (s))
    {
      const key_type old_key = extract_singleton_key (s);
      if (old_key == key)
	return s;

      /* Grow from size 1 to size 2.  */
      inc (stat_grow_from_size1_to_2);
      s = create (2);
      if (s == NULL)
	return NULL;

      s->insert_no_resize (old_key);
      s->insert_no_resize (key);
      VTV_DEBUG_ASSERT (size (s) == 2);
      return s;
    }
  s = s->resize_if_necessary();
  if (s != NULL)
    s->insert_no_resize (key);
  return s;
}

template <typename Key, class HashFcn, class Alloc>
typename insert_only_hash_sets <Key, HashFcn, Alloc>::insert_only_hash_set *
insert_only_hash_sets <Key, HashFcn, Alloc>::insert_only_hash_set::create
                                                           (size_type capacity)
{
  if (capacity <= 1)
    return NULL;

  VTV_DEBUG_ASSERT (capacity > 1 && (capacity & (capacity - 1)) == 0);
  VTV_DEBUG_ASSERT (sizeof (insert_only_hash_set) == 2 * sizeof (size_type));
  capacity = std::max <size_type> (capacity, min_capacity);
  const size_t num_bytes = sizeof (insert_only_hash_set) +
                                                  sizeof (key_type) * capacity;
  alloc_type alloc;
  insert_only_hash_set *result = (insert_only_hash_set *) alloc (num_bytes);
  result->num_buckets = capacity;
  result->num_entries = 0;
  for (size_type i = 0; i < capacity; i++)
    result->buckets[i] = (key_type) illegal_key;
  return result;
}

template <typename Key, class HashFcn, class Alloc>
void
insert_only_hash_sets<Key, HashFcn,
                                 Alloc>::insert_only_hash_set::insert_no_resize
                                                                 (key_type key)
{
  HashFcn hasher;
  const size_type capacity = num_buckets;
  VTV_DEBUG_ASSERT (capacity >= min_capacity);
  VTV_DEBUG_ASSERT (!is_reserved_key (key));
  size_type index = hasher (key) & (capacity - 1);
  key_type k = key_at_index (index);
  size_type indices_examined = 0;
  while (k != key)
    {
      ++indices_examined;
      if (k == (key_type) illegal_key)
        {
          key_at_index (index) = key;
          ++num_entries;
          return;
        }
      else
	{
	  inc_by (stat_insert_found_hash_collision,
		  hasher (k) == hasher (key));
	}
      VTV_DEBUG_ASSERT (indices_examined < capacity);
      index = next_index (index, indices_examined);
      k = key_at_index (index);
    }
}

template<typename Key, class HashFcn, class Alloc>
bool
insert_only_hash_sets<Key, HashFcn, Alloc>::insert_only_hash_set::contains
                                                           (key_type key) const
{
  inc (stat_contains_in_non_trivial_set);
  HashFcn hasher;
  const size_type capacity = num_buckets;
  size_type index = hasher (key) & (capacity - 1);
  key_type k = key_at_index (index);
  size_type indices_examined = 0;
  inc (stat_probes_in_non_trivial_set);
  while (k != key)
    {
      ++indices_examined;
      if (/*UNLIKELY*/(k == (key_type) illegal_key
		       || indices_examined == capacity))
	return false;

      index = next_index (index, indices_examined);
      k = key_at_index (index);
      inc (stat_probes_in_non_trivial_set);
    }
  return true;
}

template <typename Key, class HashFcn, class Alloc>
typename insert_only_hash_sets <Key, HashFcn, Alloc>::insert_only_hash_set *
   insert_only_hash_sets<Key, HashFcn,
                       Alloc>::insert_only_hash_set::resize_if_necessary (void)
{
  VTV_DEBUG_ASSERT (num_buckets >= min_capacity);
  size_type unused = num_buckets - num_entries;
  if (unused < (num_buckets >> 2))
    {
      inc (stat_double_the_number_of_buckets);
      size_type new_num_buckets = num_buckets * 2;
      insert_only_hash_set *s = create (new_num_buckets);
      for (size_type i = 0; i < num_buckets; i++)
        if (buckets[i] != (key_type) illegal_key)
          s->insert_no_resize (buckets[i]);
      VTV_DEBUG_ASSERT (size (this) == size (s));
      return s;
    }
  else
    return this;
}

template<typename Key, class HashFcn, class Alloc>
bool
insert_only_hash_sets<Key, HashFcn, Alloc>::create (size_type n,
						 insert_only_hash_set **handle)
  
{
  inc (stat_create);
  *handle = insert_only_hash_set::create (n);
  return (n <= 1) || (*handle != NULL);
}

template<typename Key, class HashFcn, class Alloc>
bool
insert_only_hash_sets<Key, HashFcn, Alloc>::resize (size_type n,
					         insert_only_hash_set **handle)
{
  inc (stat_resize);
  *handle = insert_only_hash_set::resize (n, *handle);
  return (n <= 1) || (*handle != NULL);
}

template<typename Key, class HashFcn, class Alloc>
bool
insert_only_hash_sets<Key, HashFcn, Alloc>::insert (key_type key,
                                                 insert_only_hash_set **handle)
{
  inc (stat_insert);
  const size_type old_size = insert_only_hash_set::size (*handle);
  *handle = insert_only_hash_set::insert (key, *handle);
  if (*handle != NULL)
    {
      const size_type delta = insert_only_hash_set::size (*handle) - old_size;
      inc_by (stat_insert_key_that_was_already_present, delta == 0);
    }
  return *handle != NULL;
}

#endif /* VTV_SET_H  */
