mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-05 22:20:24 -08:00
Use float instead of Lisp_Object for rehash_size
* src/alloc.c (purecopy_hash_table): * src/fns.c (maybe_resize_hash_table, Fmake_hash_table): (Fhash_table_rehash_size): * src/lisp.h (struct Lisp_Hash_Table.rehash_size): The rehash_size member of struct Lisp_Hash_Table is now a float, not a Lisp_Object. * src/alloc.c (purecopy_hash_table): Assign members in order. * src/fns.c (make_hash_table): Use EMACS_INT for size and float for rehash_size, instead of Lisp_Object for both. All callers changed. * src/lisp.h (DEFAULT_REHASH_SIZE): Now float, not double, and 1 smaller. * src/print.c (print_object): Simplify by calling Fhash_table_rehash_size and Fhash_table_rehash_threshold. Avoid unnecessary NILP.
This commit is contained in:
parent
5cbdaa98f9
commit
83c9c6fc1c
10 changed files with 84 additions and 79 deletions
|
|
@ -133,10 +133,10 @@ it grows automatically. This value specifies how to make the hash table
|
|||
larger, at that time.
|
||||
|
||||
If @var{rehash-size} is an integer, it should be positive, and the hash
|
||||
table grows by adding that much to the nominal size. If
|
||||
table grows by adding approximately that much to the nominal size. If
|
||||
@var{rehash-size} is floating point, it had better be greater
|
||||
than 1, and the hash table grows by multiplying the old size by that
|
||||
number.
|
||||
than 1, and the hash table grows by multiplying the old size by
|
||||
approximately that number.
|
||||
|
||||
The default value is 1.5.
|
||||
|
||||
|
|
|
|||
|
|
@ -5453,18 +5453,18 @@ purecopy_hash_table (struct Lisp_Hash_Table *table)
|
|||
pure_test.user_hash_function = purecopy (table->test.user_hash_function);
|
||||
pure_test.user_cmp_function = purecopy (table->test.user_cmp_function);
|
||||
|
||||
pure->test = pure_test;
|
||||
pure->header = table->header;
|
||||
pure->weak = purecopy (Qnil);
|
||||
pure->rehash_size = purecopy (table->rehash_size);
|
||||
pure->hash = purecopy (table->hash);
|
||||
pure->next = purecopy (table->next);
|
||||
pure->next_free = table->next_free;
|
||||
pure->index = purecopy (table->index);
|
||||
pure->count = table->count;
|
||||
pure->next_free = table->next_free;
|
||||
pure->pure = table->pure;
|
||||
pure->rehash_threshold = table->rehash_threshold;
|
||||
pure->rehash_size = table->rehash_size;
|
||||
pure->key_and_value = purecopy (table->key_and_value);
|
||||
pure->test = pure_test;
|
||||
|
||||
return pure;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,9 +64,8 @@ hash_get_category_set (Lisp_Object table, Lisp_Object category_set)
|
|||
if (NILP (XCHAR_TABLE (table)->extras[1]))
|
||||
set_char_table_extras
|
||||
(table, 1,
|
||||
make_hash_table (hashtest_equal, make_number (DEFAULT_HASH_SIZE),
|
||||
make_float (DEFAULT_REHASH_SIZE),
|
||||
DEFAULT_REHASH_THRESHOLD,
|
||||
make_hash_table (hashtest_equal, DEFAULT_HASH_SIZE,
|
||||
DEFAULT_REHASH_SIZE, DEFAULT_REHASH_THRESHOLD,
|
||||
Qnil, false));
|
||||
h = XHASH_TABLE (XCHAR_TABLE (table)->extras[1]);
|
||||
i = hash_lookup (h, category_set, &hash);
|
||||
|
|
|
|||
|
|
@ -1013,9 +1013,8 @@ syms_of_module (void)
|
|||
doc: /* Module global reference table. */);
|
||||
|
||||
Vmodule_refs_hash
|
||||
= make_hash_table (hashtest_eq, make_number (DEFAULT_HASH_SIZE),
|
||||
make_float (DEFAULT_REHASH_SIZE),
|
||||
DEFAULT_REHASH_THRESHOLD,
|
||||
= make_hash_table (hashtest_eq, DEFAULT_HASH_SIZE,
|
||||
DEFAULT_REHASH_SIZE, DEFAULT_REHASH_THRESHOLD,
|
||||
Qnil, false);
|
||||
Funintern (Qmodule_refs_hash, Qnil);
|
||||
|
||||
|
|
|
|||
95
src/fns.c
95
src/fns.c
|
|
@ -3684,13 +3684,13 @@ allocate_hash_table (void)
|
|||
`equal' or a symbol denoting a user-defined test named TEST with
|
||||
test and hash functions USER_TEST and USER_HASH.
|
||||
|
||||
Give the table initial capacity SIZE, SIZE >= 0, an integer.
|
||||
Give the table initial capacity SIZE, 0 <= SIZE <= MOST_POSITIVE_FIXNUM.
|
||||
|
||||
If REHASH_SIZE is an integer, it must be > 0, and this hash table's
|
||||
new size when it becomes full is computed by adding REHASH_SIZE to
|
||||
its old size. If REHASH_SIZE is a float, it must be > 1.0, and the
|
||||
table's new size is computed by multiplying its old size with
|
||||
REHASH_SIZE.
|
||||
If REHASH_SIZE is equal to a negative integer, this hash table's
|
||||
new size when it becomes full is computed by subtracting
|
||||
REHASH_SIZE from its old size. Otherwise it must be positive, and
|
||||
the table's new size is computed by multiplying its old size by
|
||||
REHASH_SIZE + 1.
|
||||
|
||||
REHASH_THRESHOLD must be a float <= 1.0, and > 0. The table will
|
||||
be resized when the approximate ratio of table entries to table
|
||||
|
|
@ -3704,34 +3704,31 @@ allocate_hash_table (void)
|
|||
changed after purecopy. */
|
||||
|
||||
Lisp_Object
|
||||
make_hash_table (struct hash_table_test test,
|
||||
Lisp_Object size, Lisp_Object rehash_size,
|
||||
float rehash_threshold, Lisp_Object weak,
|
||||
bool pure)
|
||||
make_hash_table (struct hash_table_test test, EMACS_INT size,
|
||||
float rehash_size, float rehash_threshold,
|
||||
Lisp_Object weak, bool pure)
|
||||
{
|
||||
struct Lisp_Hash_Table *h;
|
||||
Lisp_Object table;
|
||||
EMACS_INT index_size, sz;
|
||||
EMACS_INT index_size;
|
||||
ptrdiff_t i;
|
||||
double index_float;
|
||||
|
||||
/* Preconditions. */
|
||||
eassert (SYMBOLP (test.name));
|
||||
eassert (INTEGERP (size) && XINT (size) >= 0);
|
||||
eassert ((INTEGERP (rehash_size) && XINT (rehash_size) > 0)
|
||||
|| (FLOATP (rehash_size) && 1 < XFLOAT_DATA (rehash_size)));
|
||||
eassert (0 <= size && size <= MOST_POSITIVE_FIXNUM);
|
||||
eassert (rehash_size <= -1 || 0 < rehash_size);
|
||||
eassert (0 < rehash_threshold && rehash_threshold <= 1);
|
||||
|
||||
if (XFASTINT (size) == 0)
|
||||
size = make_number (1);
|
||||
if (size == 0)
|
||||
size = 1;
|
||||
|
||||
sz = XFASTINT (size);
|
||||
double threshold = rehash_threshold;
|
||||
index_float = sz / threshold;
|
||||
index_float = size / threshold;
|
||||
index_size = (index_float < INDEX_SIZE_BOUND + 1
|
||||
? next_almost_prime (index_float)
|
||||
: INDEX_SIZE_BOUND + 1);
|
||||
if (INDEX_SIZE_BOUND < max (index_size, 2 * sz))
|
||||
if (INDEX_SIZE_BOUND < max (index_size, 2 * size))
|
||||
error ("Hash table too large");
|
||||
|
||||
/* Allocate a table and initialize it. */
|
||||
|
|
@ -3743,14 +3740,14 @@ make_hash_table (struct hash_table_test test,
|
|||
h->rehash_threshold = rehash_threshold;
|
||||
h->rehash_size = rehash_size;
|
||||
h->count = 0;
|
||||
h->key_and_value = Fmake_vector (make_number (2 * sz), Qnil);
|
||||
h->hash = Fmake_vector (size, Qnil);
|
||||
h->next = Fmake_vector (size, make_number (-1));
|
||||
h->key_and_value = Fmake_vector (make_number (2 * size), Qnil);
|
||||
h->hash = Fmake_vector (make_number (size), Qnil);
|
||||
h->next = Fmake_vector (make_number (size), make_number (-1));
|
||||
h->index = Fmake_vector (make_number (index_size), make_number (-1));
|
||||
h->pure = pure;
|
||||
|
||||
/* Set up the free list. */
|
||||
for (i = 0; i < sz - 1; ++i)
|
||||
for (i = 0; i < size - 1; ++i)
|
||||
set_hash_next_slot (h, i, i + 1);
|
||||
h->next_free = 0;
|
||||
|
||||
|
|
@ -3810,22 +3807,21 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h)
|
|||
ptrdiff_t old_size = HASH_TABLE_SIZE (h);
|
||||
EMACS_INT new_size, index_size, nsize;
|
||||
ptrdiff_t i;
|
||||
double rehash_size = h->rehash_size;
|
||||
double index_float;
|
||||
|
||||
if (INTEGERP (h->rehash_size))
|
||||
new_size = old_size + XFASTINT (h->rehash_size);
|
||||
if (rehash_size < 0)
|
||||
new_size = old_size - rehash_size;
|
||||
else
|
||||
{
|
||||
double float_new_size = old_size * XFLOAT_DATA (h->rehash_size);
|
||||
double float_new_size = old_size * (rehash_size + 1);
|
||||
if (float_new_size < INDEX_SIZE_BOUND + 1)
|
||||
{
|
||||
new_size = float_new_size;
|
||||
if (new_size <= old_size)
|
||||
new_size = old_size + 1;
|
||||
}
|
||||
new_size = float_new_size;
|
||||
else
|
||||
new_size = INDEX_SIZE_BOUND + 1;
|
||||
}
|
||||
if (new_size <= old_size)
|
||||
new_size = old_size + 1;
|
||||
double threshold = h->rehash_threshold;
|
||||
index_float = new_size / threshold;
|
||||
index_size = (index_float < INDEX_SIZE_BOUND + 1
|
||||
|
|
@ -4408,7 +4404,7 @@ in an error.
|
|||
usage: (make-hash-table &rest KEYWORD-ARGS) */)
|
||||
(ptrdiff_t nargs, Lisp_Object *args)
|
||||
{
|
||||
Lisp_Object test, size, rehash_size, weak;
|
||||
Lisp_Object test, weak;
|
||||
bool pure;
|
||||
struct hash_table_test testdesc;
|
||||
ptrdiff_t i;
|
||||
|
|
@ -4448,18 +4444,26 @@ usage: (make-hash-table &rest KEYWORD-ARGS) */)
|
|||
pure = i && !NILP (args[i]);
|
||||
/* See if there's a `:size SIZE' argument. */
|
||||
i = get_key_arg (QCsize, nargs, args, used);
|
||||
size = i ? args[i] : Qnil;
|
||||
if (NILP (size))
|
||||
size = make_number (DEFAULT_HASH_SIZE);
|
||||
else if (!INTEGERP (size) || XINT (size) < 0)
|
||||
signal_error ("Invalid hash table size", size);
|
||||
Lisp_Object size_arg = i ? args[i] : Qnil;
|
||||
EMACS_INT size;
|
||||
if (NILP (size_arg))
|
||||
size = DEFAULT_HASH_SIZE;
|
||||
else if (NATNUMP (size_arg))
|
||||
size = XFASTINT (size_arg);
|
||||
else
|
||||
signal_error ("Invalid hash table size", size_arg);
|
||||
|
||||
/* Look for `:rehash-size SIZE'. */
|
||||
float rehash_size;
|
||||
i = get_key_arg (QCrehash_size, nargs, args, used);
|
||||
rehash_size = i ? args[i] : make_float (DEFAULT_REHASH_SIZE);
|
||||
if (! ((INTEGERP (rehash_size) && 0 < XINT (rehash_size))
|
||||
|| (FLOATP (rehash_size) && 1 < XFLOAT_DATA (rehash_size))))
|
||||
signal_error ("Invalid hash table rehash size", rehash_size);
|
||||
if (!i)
|
||||
rehash_size = DEFAULT_REHASH_SIZE;
|
||||
else if (INTEGERP (args[i]) && 0 < XINT (args[i]))
|
||||
rehash_size = - XINT (args[i]);
|
||||
else if (FLOATP (args[i]) && 0 < (float) (XFLOAT_DATA (args[i]) - 1))
|
||||
rehash_size = (float) (XFLOAT_DATA (args[i]) - 1);
|
||||
else
|
||||
signal_error ("Invalid hash table rehash size", args[i]);
|
||||
|
||||
/* Look for `:rehash-threshold THRESHOLD'. */
|
||||
i = get_key_arg (QCrehash_threshold, nargs, args, used);
|
||||
|
|
@ -4513,7 +4517,14 @@ DEFUN ("hash-table-rehash-size", Fhash_table_rehash_size,
|
|||
doc: /* Return the current rehash size of TABLE. */)
|
||||
(Lisp_Object table)
|
||||
{
|
||||
return check_hash_table (table)->rehash_size;
|
||||
double rehash_size = check_hash_table (table)->rehash_size;
|
||||
if (rehash_size < 0)
|
||||
{
|
||||
EMACS_INT s = -rehash_size;
|
||||
return make_number (min (s, MOST_POSITIVE_FIXNUM));
|
||||
}
|
||||
else
|
||||
return make_float (rehash_size + 1);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -4017,9 +4017,8 @@ xpm_make_color_table_h (void (**put_func) (Lisp_Object, const char *, int,
|
|||
{
|
||||
*put_func = xpm_put_color_table_h;
|
||||
*get_func = xpm_get_color_table_h;
|
||||
return make_hash_table (hashtest_equal, make_number (DEFAULT_HASH_SIZE),
|
||||
make_float (DEFAULT_REHASH_SIZE),
|
||||
DEFAULT_REHASH_THRESHOLD,
|
||||
return make_hash_table (hashtest_equal, DEFAULT_HASH_SIZE,
|
||||
DEFAULT_REHASH_SIZE, DEFAULT_REHASH_THRESHOLD,
|
||||
Qnil, false);
|
||||
}
|
||||
|
||||
|
|
|
|||
22
src/lisp.h
22
src/lisp.h
|
|
@ -1969,11 +1969,6 @@ struct Lisp_Hash_Table
|
|||
weakness of the table. */
|
||||
Lisp_Object weak;
|
||||
|
||||
/* When the table is resized, and this is an integer, compute the
|
||||
new size by adding this to the old size. If a float, compute the
|
||||
new size by multiplying the old size with this factor. */
|
||||
Lisp_Object rehash_size;
|
||||
|
||||
/* Vector of hash codes. If hash[I] is nil, this means that the
|
||||
I-th entry is unused. */
|
||||
Lisp_Object hash;
|
||||
|
|
@ -2008,6 +2003,13 @@ struct Lisp_Hash_Table
|
|||
ratio. */
|
||||
float rehash_threshold;
|
||||
|
||||
/* Used when the table is resized. If equal to a negative integer,
|
||||
the user rehash-size is the integer -REHASH_SIZE, and the new
|
||||
size is the old size plus -REHASH_SIZE. If positive, the user
|
||||
rehash-size is the floating-point value REHASH_SIZE + 1, and the
|
||||
new size is the old size times REHASH_SIZE + 1. */
|
||||
float rehash_size;
|
||||
|
||||
/* 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.
|
||||
This is gc_marked specially if the table is weak. */
|
||||
|
|
@ -2076,9 +2078,9 @@ enum DEFAULT_HASH_SIZE { DEFAULT_HASH_SIZE = 65 };
|
|||
|
||||
static float const DEFAULT_REHASH_THRESHOLD = 0.8125;
|
||||
|
||||
/* Default factor by which to increase the size of a hash table. */
|
||||
/* Default factor by which to increase the size of a hash table, minus 1. */
|
||||
|
||||
static double const DEFAULT_REHASH_SIZE = 1.5;
|
||||
static float const DEFAULT_REHASH_SIZE = 1.5 - 1;
|
||||
|
||||
/* Combine two integers X and Y for hashing. The result might not fit
|
||||
into a Lisp integer. */
|
||||
|
|
@ -3347,10 +3349,8 @@ extern Lisp_Object larger_vector (Lisp_Object, ptrdiff_t, ptrdiff_t);
|
|||
extern void sweep_weak_hash_tables (void);
|
||||
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,
|
||||
float rehash_threshold, Lisp_Object weak,
|
||||
bool pure);
|
||||
Lisp_Object make_hash_table (struct hash_table_test, EMACS_INT, float, float,
|
||||
Lisp_Object, bool);
|
||||
ptrdiff_t hash_lookup (struct Lisp_Hash_Table *, Lisp_Object, EMACS_UINT *);
|
||||
ptrdiff_t hash_put (struct Lisp_Hash_Table *, Lisp_Object, Lisp_Object,
|
||||
EMACS_UINT);
|
||||
|
|
|
|||
10
src/print.c
10
src/print.c
|
|
@ -1806,14 +1806,12 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
|
|||
print_object (h->weak, printcharfun, escapeflag);
|
||||
}
|
||||
|
||||
if (!NILP (h->rehash_size))
|
||||
{
|
||||
print_c_string (" rehash-size ", printcharfun);
|
||||
print_object (h->rehash_size, printcharfun, escapeflag);
|
||||
}
|
||||
print_c_string (" rehash-size ", printcharfun);
|
||||
print_object (Fhash_table_rehash_size (obj),
|
||||
printcharfun, escapeflag);
|
||||
|
||||
print_c_string (" rehash-threshold ", printcharfun);
|
||||
print_object (make_float (h->rehash_threshold),
|
||||
print_object (Fhash_table_rehash_threshold (obj),
|
||||
printcharfun, escapeflag);
|
||||
|
||||
if (h->pure)
|
||||
|
|
|
|||
|
|
@ -44,9 +44,8 @@ make_log (EMACS_INT heap_size, EMACS_INT max_stack_depth)
|
|||
a special way. This is OK as long as the object is not exposed
|
||||
to Elisp, i.e. until it is returned by *-profiler-log, after which
|
||||
it can't be used any more. */
|
||||
Lisp_Object log = make_hash_table (hashtest_profiler,
|
||||
make_number (heap_size),
|
||||
make_float (DEFAULT_REHASH_SIZE),
|
||||
Lisp_Object log = make_hash_table (hashtest_profiler, heap_size,
|
||||
DEFAULT_REHASH_SIZE,
|
||||
DEFAULT_REHASH_THRESHOLD,
|
||||
Qnil, false);
|
||||
struct Lisp_Hash_Table *h = XHASH_TABLE (log);
|
||||
|
|
|
|||
|
|
@ -12874,8 +12874,8 @@ keysyms. The default is nil, which is the same as `super'. */);
|
|||
|
||||
DEFVAR_LISP ("x-keysym-table", Vx_keysym_table,
|
||||
doc: /* Hash table of character codes indexed by X keysym codes. */);
|
||||
Vx_keysym_table = make_hash_table (hashtest_eql, make_number (900),
|
||||
make_float (DEFAULT_REHASH_SIZE),
|
||||
Vx_keysym_table = make_hash_table (hashtest_eql, 900,
|
||||
DEFAULT_REHASH_SIZE,
|
||||
DEFAULT_REHASH_THRESHOLD,
|
||||
Qnil, false);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue