emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master 7207b63 1/4: Hash table threshold is now float, not


From: Paul Eggert
Subject: [Emacs-diffs] master 7207b63 1/4: Hash table threshold is now float, not double
Date: Tue, 21 Feb 2017 18:39:23 -0500 (EST)

branch: master
commit 7207b63c8e290ddec33908ce8d38be5793388318
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>

    Hash table threshold is now float, not double
    
    Change default from 0.8 to 0.8125 so it fits in float without
    rounding glitches.
    * doc/lispref/hash.texi (Creating Hash):
    * doc/lispref/objects.texi (Hash Table Type):
    * etc/NEWS:
    Document change.
    * src/fns.c (make_hash_table, maybe_resize_hash_table)
    (Fmake_hash_table): Threshold is now float, not double.
    Be consistent about how this is rounded.
    * src/lisp.h (struct Lisp_Hash_Table.rehash_threshold):
    Change back to float, now that the other code rounds consistently.
    (DEFAULT_REHASH_THRESHOLD): Now float 0.8125 instead of double 0.8.
---
 doc/lispref/hash.texi    |  5 +++--
 doc/lispref/objects.texi |  2 +-
 etc/NEWS                 |  4 ++++
 src/fns.c                | 24 +++++++++++++-----------
 src/lisp.h               |  6 +++---
 5 files changed, 24 insertions(+), 17 deletions(-)

diff --git a/doc/lispref/hash.texi b/doc/lispref/hash.texi
index 725d19c..4ba3258 100644
--- a/doc/lispref/hash.texi
+++ b/doc/lispref/hash.texi
@@ -144,8 +144,9 @@ The default value is 1.5.
 This specifies the criterion for when the hash table is full (so
 it should be made larger).  The value, @var{threshold}, should be a
 positive floating-point number, no greater than 1.  The hash table is
-full whenever the actual number of entries exceeds this fraction
-of the nominal size.  The default for @var{threshold} is 0.8.
+full whenever the actual number of entries exceeds the nominal size
+multiplied by an approximation to this value.  The default for
address@hidden is 0.8125.
 @end table
 @end defun
 
diff --git a/doc/lispref/objects.texi b/doc/lispref/objects.texi
index fbb6658..56049af 100644
--- a/doc/lispref/objects.texi
+++ b/doc/lispref/objects.texi
@@ -1251,7 +1251,7 @@ and contents, like this:
 @example
 (make-hash-table)
      @result{} #s(hash-table size 65 test eql rehash-size 1.5
-                             rehash-threshold 0.8 data ())
+                             rehash-threshold 0.8125 data ())
 @end example
 
 @noindent
diff --git a/etc/NEWS b/etc/NEWS
index 143e465..9355dff 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -904,6 +904,10 @@ consistency with the new functions.  For compatibility, 
'sxhash'
 remains as an alias to 'sxhash-equal'.
 
 +++
+** 'make-hash-table' now defaults to a rehash threshold of 0.8125
+instead of 0.8, to avoid rounding glitches.
+
++++
 ** New function 'add-variable-watcher' can be used to call a function
 when a symbol's value is changed.  This is used to implement the new
 debugger command 'debug-on-variable-change'.
diff --git a/src/fns.c b/src/fns.c
index 3fed92d..2a66531 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -3663,8 +3663,8 @@ allocate_hash_table (void)
    REHASH_SIZE.
 
    REHASH_THRESHOLD must be a float <= 1.0, and > 0.  The table will
-   be resized when the ratio of (number of entries in the table) /
-   (table size) is >= REHASH_THRESHOLD.
+   be resized when the approximate ratio of table entries to table
+   size exceeds REHASH_THRESHOLD.
 
    WEAK specifies the weakness of the table.  If non-nil, it must be
    one of the symbols `key', `value', `key-or-value', or `key-and-value'.
@@ -3676,7 +3676,7 @@ allocate_hash_table (void)
 Lisp_Object
 make_hash_table (struct hash_table_test test,
                 Lisp_Object size, Lisp_Object rehash_size,
-                double rehash_threshold, Lisp_Object weak,
+                float rehash_threshold, Lisp_Object weak,
                  bool pure)
 {
   struct Lisp_Hash_Table *h;
@@ -3690,13 +3690,14 @@ make_hash_table (struct hash_table_test test,
   eassert (INTEGERP (size) && XINT (size) >= 0);
   eassert ((INTEGERP (rehash_size) && XINT (rehash_size) > 0)
           || (FLOATP (rehash_size) && 1 < XFLOAT_DATA (rehash_size)));
-  eassert (0 < rehash_threshold && rehash_threshold <= 1.0);
+  eassert (0 < rehash_threshold && rehash_threshold <= 1);
 
   if (XFASTINT (size) == 0)
     size = make_number (1);
 
   sz = XFASTINT (size);
-  index_float = sz / rehash_threshold;
+  double threshold = rehash_threshold;
+  index_float = sz / threshold;
   index_size = (index_float < INDEX_SIZE_BOUND + 1
                ? next_almost_prime (index_float)
                : INDEX_SIZE_BOUND + 1);
@@ -3795,7 +3796,8 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h)
          else
            new_size = INDEX_SIZE_BOUND + 1;
        }
-      index_float = new_size / h->rehash_threshold;
+      double threshold = h->rehash_threshold;
+      index_float = new_size / threshold;
       index_size = (index_float < INDEX_SIZE_BOUND + 1
                    ? next_almost_prime (index_float)
                    : INDEX_SIZE_BOUND + 1);
@@ -4370,8 +4372,8 @@ amount.  If it is a float, it must be > 1.0, and the new 
size is the
 old size multiplied by that factor.  Default is 1.5.
 
 :rehash-threshold THRESHOLD -- THRESHOLD must a float > 0, and <= 1.0.
-Resize the hash table when the ratio (number of entries / table size)
-is greater than or equal to THRESHOLD.  Default is 0.8.
+Resize the hash table when the ratio (table entries / table size)
+exceeds an approximation to THRESHOLD.  Default is 0.8125.
 
 :weakness WEAK -- WEAK must be one of nil, t, `key', `value',
 `key-or-value', or `key-and-value'.  If WEAK is not nil, the table
@@ -4390,7 +4392,6 @@ usage: (make-hash-table &rest KEYWORD-ARGS)  */)
   (ptrdiff_t nargs, Lisp_Object *args)
 {
   Lisp_Object test, size, rehash_size, weak;
-  double rehash_threshold;
   bool pure;
   struct hash_table_test testdesc;
   ptrdiff_t i;
@@ -4445,8 +4446,9 @@ usage: (make-hash-table &rest KEYWORD-ARGS)  */)
 
   /* Look for `:rehash-threshold THRESHOLD'.  */
   i = get_key_arg (QCrehash_threshold, nargs, args, used);
-  rehash_threshold = (!i ? DEFAULT_REHASH_THRESHOLD
-                     : FLOATP (args[i]) ? XFLOAT_DATA (args[i]) : 0);
+  float rehash_threshold = (!i ? DEFAULT_REHASH_THRESHOLD
+                           : !FLOATP (args[i]) ? 0
+                           : (float) XFLOAT_DATA (args[i]));
   if (! (0 < rehash_threshold && rehash_threshold <= 1))
     signal_error ("Invalid hash table rehash threshold", args[i]);
 
diff --git a/src/lisp.h b/src/lisp.h
index be42b33..6e02526 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -2004,7 +2004,7 @@ struct Lisp_Hash_Table
 
   /* Resize hash table when number of entries / table size is >= this
      ratio.  */
-  double rehash_threshold;
+  float rehash_threshold;
 
   /* Vector of keys and values.  The key of item I is found at index
      2 * I, the value is found at index 2 * I + 1.
@@ -2088,7 +2088,7 @@ enum DEFAULT_HASH_SIZE { DEFAULT_HASH_SIZE = 65 };
    value gives the ratio of current entries in the hash table and the
    size of the hash table.  */
 
-static double const DEFAULT_REHASH_THRESHOLD = 0.8;
+static float const DEFAULT_REHASH_THRESHOLD = 0.8125;
 
 /* Default factor by which to increase the size of a hash table.  */
 
@@ -3363,7 +3363,7 @@ EMACS_UINT hash_string (char const *, ptrdiff_t);
 EMACS_UINT sxhash (Lisp_Object, int);
 Lisp_Object make_hash_table (struct hash_table_test test,
                             Lisp_Object size, Lisp_Object rehash_size,
-                            double rehash_threshold, Lisp_Object weak,
+                            float rehash_threshold, Lisp_Object weak,
                              bool pure);
 ptrdiff_t hash_lookup (struct Lisp_Hash_Table *, Lisp_Object, EMACS_UINT *);
 ptrdiff_t hash_put (struct Lisp_Hash_Table *, Lisp_Object, Lisp_Object,



reply via email to

[Prev in Thread] Current Thread [Next in Thread]