Browse Source

putil: remove no-longer-used WeakKeyHashMap for now

rdb 7 years ago
parent
commit
30446952cb

+ 0 - 1
panda/src/putil/p3putil_composite2.cxx

@@ -25,7 +25,6 @@
 #include "vector_typedWritable.cxx"
 #include "vector_ushort.cxx"
 #include "vector_writable.cxx"
-#include "weakKeyHashMap.cxx"
 #include "writableConfigurable.cxx"
 #include "writableParam.cxx"
 

+ 0 - 627
panda/src/putil/weakKeyHashMap.I

@@ -1,627 +0,0 @@
-/**
- * PANDA 3D SOFTWARE
- * Copyright (c) Carnegie Mellon University.  All rights reserved.
- *
- * All use of this software is subject to the terms of the revised BSD
- * license.  You should have received a copy of this license along
- * with this source code in a file named "LICENSE."
- *
- * @file weakKeyHashMap.I
- * @author rdb
- * @date 2015-07-13
- */
-
-/**
- *
- */
-template<class Key, class Value>
-INLINE WeakKeyHashMap<Key, Value>::
-WeakKeyHashMap() :
-  _table(nullptr),
-  _deleted_chain(nullptr),
-  _table_size(0),
-  _num_entries(0)
-{
-}
-
-/**
- *
- */
-template<class Key, class Value>
-INLINE WeakKeyHashMap<Key, Value>::
-~WeakKeyHashMap() {
-  clear();
-}
-
-/**
- * Quickly exchanges the contents of this map and the other map.
- */
-template<class Key, class Value>
-INLINE void WeakKeyHashMap<Key, Value>::
-swap(WeakKeyHashMap<Key, Value> &other) {
-  TableEntry *t0 = _table;
-  _table = other._table;
-  other._table = t0;
-
-  DeletedBufferChain *t1 = _deleted_chain;
-  _deleted_chain = other._deleted_chain;
-  other._deleted_chain = t1;
-
-  size_t t2 = _table_size;
-  _table_size = other._table_size;
-  other._table_size = t2;
-
-  size_t t3 = _num_entries;
-  _num_entries = other._num_entries;
-  other._num_entries = t3;
-}
-
-/**
- * Searches for the indicated key in the table.  Returns its index number if
- * it is found, or -1 if it is not present in the table.
- */
-template<class Key, class Value>
-int WeakKeyHashMap<Key, Value>::
-find(const Key *key) const {
-  if (_table_size == 0) {
-    // Special case: the table is empty.
-    return -1;
-  }
-
-  size_t index = get_hash(key);
-  if (!has_element(index)) {
-    return -1;
-  }
-  if (is_element(index, key)) {
-    return index;
-  }
-
-  // There was some other key at the hashed slot.  That's a hash conflict.
-  // Maybe our entry was recorded at a later slot position; scan the
-  // subsequent positions until we find the entry or an unused slot,
-  // indicating the end of the scan.
-  size_t i = index;
-  i = (i + 1) & (_table_size - 1);
-  while (i != index && has_element(i)) {
-    if (is_element(i, key)) {
-      return i;
-    }
-    i = (i + 1) & (_table_size - 1);
-  }
-
-  // The key is not in the table.
-  return -1;
-}
-
-/**
- * Records the indicated key/data pair in the map.  If the key was already
- * present, silently replaces it.  Returns the index at which it was stored.
- */
-template<class Key, class Value>
-int WeakKeyHashMap<Key, Value>::
-store(const Key *key, const Value &data) {
-  if (_table_size == 0) {
-    // Special case: the first key in an empty table.
-    nassertr(_num_entries == 0, -1);
-    new_table();
-    size_t index = get_hash(key);
-    store_new_element(index, key, data);
-    ++_num_entries;
-#ifdef _DEBUG
-    nassertr(validate(), index);
-#endif
-    return index;
-  }
-
-  size_t index = get_hash(key);
-  if (!has_element(index)) {
-    // This element is not already in the map; add it.
-    if (consider_expand_table()) {
-      return store(key, data);
-    }
-    store_new_element(index, key, data);
-    ++_num_entries;
-#ifdef _DEBUG
-    nassertr(validate(), index);
-#endif
-    return index;
-  }
-  if (is_element(index, key)) {
-    // This element is already in the map; replace the data at that key.
-    _table[index]._data = data;
-#ifdef _DEBUG
-    nassertr(validate(), index);
-#endif
-    return index;
-  }
-
-  // There was some other key at the hashed slot.  That's a hash conflict.
-  // Record this entry at a later position.
-  size_t i = index;
-  i = (i + 1) & (_table_size - 1);
-  while (i != index) {
-    if (!has_element(i)) {
-      if (consider_expand_table()) {
-        return store(key, data);
-      }
-      store_new_element(i, key, data);
-      ++_num_entries;
-#ifdef _DEBUG
-      nassertr(validate(), i);
-#endif
-      return i;
-    }
-    if (is_element(i, key)) {
-      _table[i]._data = data;
-#ifdef _DEBUG
-      nassertr(validate(), i);
-#endif
-      return i;
-    }
-    i = (i + 1) & (_table_size - 1);
-  }
-
-  // Shouldn't get here unless _num_entries == _table_size, which shouldn't be
-  // possible due to consider_expand_table().
-  nassertr(false, -1);
-  return -1;  // To satisfy compiler
-}
-
-/**
- * Removes the indicated key and its associated data from the table.  Returns
- * true if the key was removed, false if it was not present.
- */
-template<class Key, class Value>
-INLINE bool WeakKeyHashMap<Key, Value>::
-remove(const Key *key) {
-  int index = find(key);
-  if (index == -1) {
-    return false;
-  }
-  remove_element(index);
-  return true;
-}
-
-/**
- * Completely empties the table.
- */
-template<class Key, class Value>
-void WeakKeyHashMap<Key, Value>::
-clear() {
-  if (_table_size != 0) {
-    for (size_t i = 0; i < _table_size; ++i) {
-      if (get_exists_array()[i] != 0) {
-        clear_element(i);
-      }
-    }
-
-    _deleted_chain->deallocate(_table, TypeHandle::none());
-    _table = nullptr;
-    _deleted_chain = nullptr;
-    _table_size = 0;
-    _num_entries = 0;
-  }
-}
-
-/**
- * Returns a modifiable reference to the data associated with the indicated
- * key, or creates a new data entry and returns its reference.
- */
-template<class Key, class Value>
-INLINE Value &WeakKeyHashMap<Key, Value>::
-operator [] (const Key *key) {
-  int index = find(key);
-  if (index == -1) {
-    index = store(key, Value());
-  }
-  return modify_data(index);
-}
-
-/**
- * Returns the total number of slots in the table.
- */
-template<class Key, class Value>
-INLINE size_t WeakKeyHashMap<Key, Value>::
-get_size() const {
-  return _table_size;
-}
-
-/**
- * Returns true if there is an element stored in the nth slot, false
- * otherwise.
- *
- * n should be in the range 0 <= n < get_size().
- */
-template<class Key, class Value>
-INLINE bool WeakKeyHashMap<Key, Value>::
-has_element(size_t n) const {
-  nassertr(n < _table_size, false);
-  return (get_exists_array()[n] != 0 && !_table[n]._key.was_deleted());
-}
-
-/**
- * Returns the key in the nth slot of the table.
- *
- * It is an error to call this if there is nothing stored in the nth slot (use
- * has_element() to check this first).  n should be in the range 0 <= n <
- * get_size().
- */
-template<class Key, class Value>
-INLINE const Key *WeakKeyHashMap<Key, Value>::
-get_key(size_t n) const {
-  nassertr(has_element(n), _table[n]._key);
-  return _table[n]._key;
-}
-
-/**
- * Returns the data in the nth slot of the table.
- *
- * It is an error to call this if there is nothing stored in the nth slot (use
- * has_element() to check this first).  n should be in the range 0 <= n <
- * get_size().
- */
-template<class Key, class Value>
-INLINE const Value &WeakKeyHashMap<Key, Value>::
-get_data(size_t n) const {
-  nassertr(has_element(n), _table[n]._data);
-  return _table[n]._data;
-}
-
-/**
- * Returns a modifiable reference to the data in the nth slot of the table.
- *
- * It is an error to call this if there is nothing stored in the nth slot (use
- * has_element() to check this first).  n should be in the range 0 <= n <
- * get_size().
- */
-template<class Key, class Value>
-INLINE Value &WeakKeyHashMap<Key, Value>::
-modify_data(size_t n) {
-  nassertr(has_element(n), _table[n]._data);
-  return _table[n]._data;
-}
-
-/**
- * Changes the data for the nth slot of the table.
- *
- * It is an error to call this if there is nothing stored in the nth slot (use
- * has_element() to check this first).  n should be in the range 0 <= n <
- * get_size().
- */
-template<class Key, class Value>
-INLINE void WeakKeyHashMap<Key, Value>::
-set_data(size_t n, const Value &data) {
-  nassertv(has_element(n));
-  _table[n]._data = data;
-}
-
-/**
- * Changes the data for the nth slot of the table.
- *
- * It is an error to call this if there is nothing stored in the nth slot (use
- * has_element() to check this first).  n should be in the range 0 <= n <
- * get_size().
- */
-template<class Key, class Value>
-INLINE void WeakKeyHashMap<Key, Value>::
-set_data(size_t n, Value &&data) {
-  nassertv(has_element(n));
-  _table[n]._data = std::move(data);
-}
-
-/**
- * Removes the nth slot from the table.
- *
- * It is an error to call this if there is nothing stored in the nth slot (use
- * has_element() to check this first).  n should be in the range 0 <= n <
- * get_size().
- */
-template<class Key, class Value>
-void WeakKeyHashMap<Key, Value>::
-remove_element(size_t n) {
-  nassertv(get_exists_array()[n] != 0);
-
-  clear_element(n);
-  nassertv(_num_entries > 0);
-  --_num_entries;
-
-  // Now we have put a hole in the table.  If there was a hash conflict in the
-  // slot following this one, we have to move it down to close the hole.
-  size_t i = n;
-  i = (i + 1) & (_table_size - 1);
-  while (get_exists_array()[i] != 0) {
-    if (_table[i]._key.was_deleted()) {
-      // It was deleted.  Forget about it.
-      clear_element(i);
-      --_num_entries;
-    } else {
-      size_t wants_index = get_hash(_table[i]._key.get_orig());
-      if (wants_index != i) {
-        // This one was a hash conflict; try to put it where it belongs.  We
-        // can't just put it in n, since maybe it belongs somewhere after n.
-        while (wants_index != i && has_element(wants_index)) {
-          // Hash conflict; move it up.
-          wants_index = (wants_index + 1) & (_table_size - 1);
-        }
-        if (wants_index != i) {
-          store_new_element(wants_index, _table[i]._key, _table[i]._data);
-          clear_element(i);
-        }
-      }
-    }
-
-    // Continue until we encounter the next unused slot.  Until we do, we
-    // can't be sure we've found all of the potential hash conflicts.
-    i = (i + 1) & (_table_size - 1);
-  }
-
-#ifdef _DEBUG
-  nassertv(validate());
-#endif
-}
-
-/**
- * Returns the number of active entries in the table.  This is not necessarily
- * related to the number of slots in the table as reported by get_size().  Use
- * get_size() to iterate through all of the slots, not get_num_entries().
- *
- * This is merely an upper bound on the number of entries; it may also count
- * false positives for pointers that were recently deleted.
- */
-template<class Key, class Value>
-INLINE size_t WeakKeyHashMap<Key, Value>::
-get_num_entries() const {
-  return _num_entries;
-}
-
-/**
- * Returns true if the table is empty; i.e.  get_num_entries() == 0.  This may
- * return a false negatives if a pointer was recently deleted; if this returns
- * true, though, you can be sure it's empty.
- */
-template<class Key, class Value>
-INLINE bool WeakKeyHashMap<Key, Value>::
-is_empty() const {
-  return (_num_entries == 0);
-}
-
-/**
- *
- */
-template<class Key, class Value>
-void WeakKeyHashMap<Key, Value>::
-output(std::ostream &out) const {
-  out << "WeakKeyHashMap (" << _num_entries << " entries): [";
-  for (size_t i = 0; i < _table_size; ++i) {
-    if (get_exists_array()[i] == 0) {
-      out << " *";
-
-    } else {
-      out << " " << _table[i]._key;
-      size_t index = get_hash(_table[i]._key.get_orig());
-      if (index != i) {
-        // This was misplaced as the result of a hash conflict.  Report how
-        // far off it is.
-        out << "(" << ((_table_size + i - index) & (_table_size - 1)) << ")";
-      }
-    }
-  }
-  out << " ]";
-}
-
-/**
- *
- */
-template<class Key, class Value>
-void WeakKeyHashMap<Key, Value>::
-write(std::ostream &out) const {
-  output(out);
-  out << "\n";
-}
-
-/**
- * Returns true if the internal table appears to be consistent, false if there
- * are some internal errors.
- */
-template<class Key, class Value>
-bool WeakKeyHashMap<Key, Value>::
-validate() const {
-  size_t count = 0;
-
-  const unsigned char *exists_array = get_exists_array();
-
-  for (size_t i = 0; i < _table_size; ++i) {
-    if (exists_array[i] != 0) {
-      ++count;
-      if (_table[i]._key.was_deleted()) {
-        continue;
-      }
-      size_t ideal_index = get_hash(_table[i]._key.get_orig());
-      size_t wants_index = ideal_index;
-      while (wants_index != i && exists_array[wants_index] != 0) {
-        wants_index = (wants_index + 1) & (_table_size - 1);
-      }
-      if (wants_index != i) {
-        util_cat.error()
-          << "WeakKeyHashMap is invalid: key " << _table[i]._key
-          << " should be in slot " << wants_index << " instead of "
-          << i << " (ideal is " << ideal_index << ")\n";
-        write(util_cat.error(false));
-        return false;
-      }
-    }
-  }
-
-  if (count != _num_entries) {
-    util_cat.error()
-      << "WeakKeyHashMap is invalid: reports " << _num_entries
-      << " entries, actually has " << count << "\n";
-    write(util_cat.error(false));
-    return false;
-  }
-
-  return true;
-}
-
-/**
- * Computes an appropriate index number to store the given pointer.
- */
-template<class Key, class Value>
-INLINE size_t WeakKeyHashMap<Key, Value>::
-get_hash(const Key *key) const {
-  /*
-  // We want a hash constant 0 < k < 1.  This one is suggested by Knuth:
-  static const double hash_constant = (sqrt(5.0) - 1.0) / 2.0;
-  double f = ((double)(size_t)key * hash_constant);
-  f -= floor(f);
-  return (size_t)floor(f * _table_size);
-  */
-
-  return (((size_t)key * (size_t)9973) >> 8) & (_table_size - 1);
-}
-
-/**
- * Returns true if element n matches key.
- */
-template<class Key, class Value>
-INLINE bool WeakKeyHashMap<Key, Value>::
-is_element(size_t n, const Key *key) const {
-  nassertr(has_element(n), false);
-  return _table[n]._key == key;
-}
-
-/**
- * Constructs a new TableEntry at position n, storing the indicated key and
- * value.
- */
-template<class Key, class Value>
-INLINE void WeakKeyHashMap<Key, Value>::
-store_new_element(size_t n, const Key *key, const Value &data) {
-  if (get_exists_array()[n] != 0) {
-    // There was already an element in this spot.  This can happen if it was a
-    // pointer that had already been deleted.
-    nassertv(_table[n]._key.was_deleted());
-    _table[n].~TableEntry();
-    --_num_entries;
-  }
-  new(&_table[n]) TableEntry(key, data);
-  get_exists_array()[n] = true;
-}
-
-/**
- * Destructs the TableEntry at position n.
- */
-template<class Key, class Value>
-INLINE void WeakKeyHashMap<Key, Value>::
-clear_element(size_t n) {
-  _table[n].~TableEntry();
-  get_exists_array()[n] = false;
-}
-
-/**
- * Returns the beginning of the array of _table_size unsigned chars that are
- * the boolean flags for whether each element exists (has been constructed)
- * within the table.
- */
-template<class Key, class Value>
-INLINE unsigned char *WeakKeyHashMap<Key, Value>::
-get_exists_array() const {
-  return (unsigned char *)(_table + _table_size);
-}
-
-/**
- * Allocates a brand new table.
- */
-template<class Key, class Value>
-void WeakKeyHashMap<Key, Value>::
-new_table() {
-  nassertv(_table_size == 0 && _num_entries == 0);
-
-  // Pick a good initial table size.  For now, we make it really small.  Maybe
-  // that's the right answer.
-  _table_size = 4;
-
-  // We allocate enough bytes for _table_size elements of TableEntry, plus
-  // _table_size more bytes at the end (for the exists array).
-  size_t alloc_size = _table_size * sizeof(TableEntry) + _table_size;
-
-  _deleted_chain = memory_hook->get_deleted_chain(alloc_size);
-  _table = (TableEntry *)_deleted_chain->allocate(alloc_size, TypeHandle::none());
-  memset(get_exists_array(), 0, _table_size);
-}
-
-/**
- * Expands the table if it will need it (assuming one more element is about to
- * be added).  Returns true if the table was modified, false otherwise.
- */
-template<class Key, class Value>
-INLINE bool WeakKeyHashMap<Key, Value>::
-consider_expand_table() {
-  if (_num_entries >= (_table_size >> 1)) {
-    // Actually, first, we should see if there are any deleted pointers.
-    // Clean those up and see how much space we save.
-    for (size_t i = 0; i < _table_size; ++i) {
-      if (get_exists_array()[i] != 0 && _table[i]._key.was_deleted()) {
-        remove_element(i);
-      }
-    }
-    if (_num_entries >= (_table_size >> 1)) {
-      // Still not enough space.
-      expand_table();
-    }
-    return true;
-  }
-  return false;
-}
-
-/**
- * Doubles the size of the existing table.
- */
-template<class Key, class Value>
-void WeakKeyHashMap<Key, Value>::
-expand_table() {
-  nassertv(_table_size != 0);
-
-  WeakKeyHashMap<Key, Value> old_map;
-  swap(old_map);
-
-  // Double the table size.
-  size_t old_table_size = old_map._table_size;
-  _table_size = (old_table_size << 1);
-  nassertv(_table == nullptr);
-
-  // We allocate enough bytes for _table_size elements of TableEntry, plus
-  // _table_size more bytes at the end (for the exists array).
-  size_t alloc_size = _table_size * sizeof(TableEntry) + _table_size;
-  _deleted_chain = memory_hook->get_deleted_chain(alloc_size);
-  _table = (TableEntry *)_deleted_chain->allocate(alloc_size, TypeHandle::none());
-  unsigned char *exists_array = get_exists_array();
-  memset(exists_array, 0, _table_size);
-  nassertv(_num_entries == 0);
-
-  // Now copy the entries from the old table into the new table.
-  for (size_t i = 0; i < old_table_size; ++i) {
-    if (old_map.has_element(i)) {
-      size_t new_index = get_hash(old_map._table[i]._key.get_orig());
-
-      while (exists_array[new_index] != 0) {
-        // Hash conflict;  look for a better spot.  This has to succeed.
-        new_index = (new_index + 1) & (_table_size - 1);
-      }
-
-      // Use C++11 rvalue references to invoke the move constructor, which may
-      // be more efficient.
-      new(&_table[new_index]) TableEntry(std::move(old_map._table[i]));
-      exists_array[new_index] = true;
-      ++_num_entries;
-    }
-  }
-
-  nassertv(validate());
-  nassertv(old_map.validate());
-
-  // Note that since has_element(i) also checks whether the pointer has been
-  // deleted, we may end up with fewer entries than we started with.  Good
-  // riddance.
-  nassertv(_num_entries <= old_map._num_entries);
-}

+ 0 - 14
panda/src/putil/weakKeyHashMap.cxx

@@ -1,14 +0,0 @@
-/**
- * PANDA 3D SOFTWARE
- * Copyright (c) Carnegie Mellon University.  All rights reserved.
- *
- * All use of this software is subject to the terms of the revised BSD
- * license.  You should have received a copy of this license along
- * with this source code in a file named "LICENSE."
- *
- * @file weakKeyHashMap.cxx
- * @author rdb
- * @date 2015-07-13
- */
-
-#include "weakKeyHashMap.h"

+ 0 - 108
panda/src/putil/weakKeyHashMap.h

@@ -1,108 +0,0 @@
-/**
- * PANDA 3D SOFTWARE
- * Copyright (c) Carnegie Mellon University.  All rights reserved.
- *
- * All use of this software is subject to the terms of the revised BSD
- * license.  You should have received a copy of this license along
- * with this source code in a file named "LICENSE."
- *
- * @file weakKeyHashMap.h
- * @author rdb
- * @date 2015-07-13
- */
-
-#ifndef WEAKKEYHASHMAP_H
-#define WEAKKEYHASHMAP_H
-
-#include "pandabase.h"
-#include "pvector.h"
-#include "config_putil.h"
-#include "weakPointerTo.h"
-
-/**
- * This is a variation on WeakKeyHashMap that stores weak pointers as keys,
- * and automatically frees up entries from the map when the associated key has
- * been deleted.
- *
- * This is more efficient than using a naive map of WeakPointerTo keys since
- * that would incur the cost of constructing a weak reference every time a
- * find operation is used.
- */
-template<class Key, class Value>
-class WeakKeyHashMap {
-public:
-#ifndef CPPPARSER
-  INLINE WeakKeyHashMap();
-  INLINE ~WeakKeyHashMap();
-
-  INLINE void swap(WeakKeyHashMap &other);
-
-  int find(const Key *key) const;
-  int store(const Key *key, const Value &data);
-  INLINE bool remove(const Key *key);
-  void clear();
-
-  INLINE Value &operator [] (const Key *key);
-
-  INLINE size_t get_size() const;
-  INLINE bool has_element(size_t n) const;
-  INLINE const Key *get_key(size_t n) const;
-  INLINE const Value &get_data(size_t n) const;
-  INLINE Value &modify_data(size_t n);
-  INLINE void set_data(size_t n, const Value &data);
-  INLINE void set_data(size_t n, Value &&data);
-  void remove_element(size_t n);
-
-  INLINE size_t get_num_entries() const;
-  INLINE bool is_empty() const;
-
-  void output(std::ostream &out) const;
-  void write(std::ostream &out) const;
-  bool validate() const;
-
-private:
-  INLINE size_t get_hash(const Key *key) const;
-
-  INLINE bool is_element(size_t n, const Key *key) const;
-  INLINE void store_new_element(size_t n, const Key *key, const Value &data);
-  INLINE void clear_element(size_t n);
-  INLINE unsigned char *get_exists_array() const;
-
-  void new_table();
-  INLINE bool consider_expand_table();
-  void expand_table();
-
-  class TableEntry {
-  public:
-    INLINE TableEntry(const Key *key, const Value &data) :
-      _key(key),
-      _data(data) {}
-    INLINE TableEntry(const TableEntry &copy) :
-      _key(copy._key),
-      _data(copy._data) {}
-    INLINE TableEntry(TableEntry &&from) noexcept :
-      _key(std::move(from._key)),
-      _data(std::move(from._data)) {}
-
-    WCPT(Key) _key;
-    Value _data;
-  };
-
-  TableEntry *_table;
-  DeletedBufferChain *_deleted_chain;
-  size_t _table_size;
-  size_t _num_entries;
-#endif  // CPPPARSER
-};
-
-template<class Key, class Value>
-inline std::ostream &operator << (std::ostream &out, const WeakKeyHashMap<Key, Value> &shm) {
-  shm.output(out);
-  return out;
-}
-
-#ifndef CPPPARSER
-#include "weakKeyHashMap.I"
-#endif  // CPPPARSER
-
-#endif