1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-04-28 01:00:52 -07:00

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.
This commit is contained in:
Paul Eggert 2017-02-21 15:31:29 -08:00
parent f2191691d4
commit 7207b63c8e
5 changed files with 24 additions and 17 deletions

View 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

View 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

View file

@ -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

View file

@ -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]);

View 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,