]> git.eshelyaron.com Git - emacs.git/commitdiff
Hash table threshold is now float, not double
authorPaul Eggert <eggert@cs.ucla.edu>
Tue, 21 Feb 2017 23:31:29 +0000 (15:31 -0800)
committerPaul Eggert <eggert@cs.ucla.edu>
Tue, 21 Feb 2017 23:39:17 +0000 (15:39 -0800)
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
doc/lispref/objects.texi
etc/NEWS
src/fns.c
src/lisp.h

index 725d19c3bdcb6ec386adb4baefcb8c8ea7b7f32c..4ba3258d1899e8ecc900c90038f5111e97691752 100644 (file)
@@ -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
+@var{threshold} is 0.8125.
 @end table
 @end defun
 
index fbb66582f2983b576b6a21bb67deb08cf2b2c2ef..56049af60a1cdd4ef7c63c14d68db3f4d849d014 100644 (file)
@@ -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
index 143e4655def3938b9ef91658ea65ab349b68574c..9355dff7a08bdc1cef0119a14bb8afa32f9e3999 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -903,6 +903,10 @@ two objects are 'eq' ('eql'), then the result of 'sxhash-eq'
 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
index 3fed92dfec1e6a3fb658ea205a6d6b1044dc397f..2a6653144bcadeb6a2d23d509b3a6cc020c91e14 100644 (file)
--- 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]);
 
index be42b3354e21294446bd9d37989e88d121f69a9b..6e0252621a6ef19fee688b1fa9d94729a5d2b277 100644 (file)
@@ -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,