aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMattias EngdegÄrd2023-11-06 13:25:07 +0100
committerMattias EngdegÄrd2024-01-12 18:02:14 +0100
commit228e9000181b06e5fd3d775c4c9a31c48ee2a231 (patch)
treec5db415cd726866030820bece845db6be7069808 /src
parent10cfbda88413c8ac0d254553fd537447b890a885 (diff)
downloademacs-228e9000181b06e5fd3d775c4c9a31c48ee2a231.tar.gz
emacs-228e9000181b06e5fd3d775c4c9a31c48ee2a231.zip
Add internal hash-table debug functions
These are useful for measuring hashing and collisions. * src/fns.c (Finternal__hash_table_histogram) (Finternal__hash_table_buckets, Finternal__hash_table_index_size): New.
Diffstat (limited to 'src')
-rw-r--r--src/fns.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/fns.c b/src/fns.c
index c03aea02397..4ce855827c9 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -5560,6 +5560,68 @@ returns nil, then (funcall TEST x1 x2) also returns nil. */)
5560 return Fput (name, Qhash_table_test, list2 (test, hash)); 5560 return Fput (name, Qhash_table_test, list2 (test, hash));
5561} 5561}
5562 5562
5563DEFUN ("internal--hash-table-histogram",
5564 Finternal__hash_table_histogram,
5565 Sinternal__hash_table_histogram,
5566 1, 1, 0,
5567 doc: /* Bucket size histogram of HASH-TABLE. Internal use only. */)
5568 (Lisp_Object hash_table)
5569{
5570 struct Lisp_Hash_Table *h = check_hash_table (hash_table);
5571 ptrdiff_t size = HASH_TABLE_SIZE (h);
5572 ptrdiff_t *freq = xzalloc (size * sizeof *freq);
5573 ptrdiff_t index_size = ASIZE (h->index);
5574 for (ptrdiff_t i = 0; i < index_size; i++)
5575 {
5576 ptrdiff_t n = 0;
5577 for (ptrdiff_t j = HASH_INDEX (h, i); j != -1; j = HASH_NEXT (h, j))
5578 n++;
5579 if (n > 0)
5580 freq[n - 1]++;
5581 }
5582 Lisp_Object ret = Qnil;
5583 for (ptrdiff_t i = 0; i < size; i++)
5584 if (freq[i] > 0)
5585 ret = Fcons (Fcons (make_int (i + 1), make_int (freq[i])),
5586 ret);
5587 xfree (freq);
5588 return Fnreverse (ret);
5589}
5590
5591DEFUN ("internal--hash-table-buckets",
5592 Finternal__hash_table_buckets,
5593 Sinternal__hash_table_buckets,
5594 1, 1, 0,
5595 doc: /* (KEY . HASH) in HASH-TABLE, grouped by bucket.
5596Internal use only. */)
5597 (Lisp_Object hash_table)
5598{
5599 struct Lisp_Hash_Table *h = check_hash_table (hash_table);
5600 Lisp_Object ret = Qnil;
5601 ptrdiff_t index_size = ASIZE (h->index);
5602 for (ptrdiff_t i = 0; i < index_size; i++)
5603 {
5604 Lisp_Object bucket = Qnil;
5605 for (ptrdiff_t j = HASH_INDEX (h, i); j != -1; j = HASH_NEXT (h, j))
5606 bucket = Fcons (Fcons (HASH_KEY (h, j), HASH_HASH (h, j)),
5607 bucket);
5608 if (!NILP (bucket))
5609 ret = Fcons (Fnreverse (bucket), ret);
5610 }
5611 return Fnreverse (ret);
5612}
5613
5614DEFUN ("internal--hash-table-index-size",
5615 Finternal__hash_table_index_size,
5616 Sinternal__hash_table_index_size,
5617 1, 1, 0,
5618 doc: /* Index size of HASH-TABLE. Internal use only. */)
5619 (Lisp_Object hash_table)
5620{
5621 struct Lisp_Hash_Table *h = check_hash_table (hash_table);
5622 ptrdiff_t index_size = ASIZE (h->index);
5623 return make_int (index_size);
5624}
5563 5625
5564 5626
5565/************************************************************************ 5627/************************************************************************
@@ -6250,6 +6312,9 @@ syms_of_fns (void)
6250 defsubr (&Sremhash); 6312 defsubr (&Sremhash);
6251 defsubr (&Smaphash); 6313 defsubr (&Smaphash);
6252 defsubr (&Sdefine_hash_table_test); 6314 defsubr (&Sdefine_hash_table_test);
6315 defsubr (&Sinternal__hash_table_histogram);
6316 defsubr (&Sinternal__hash_table_buckets);
6317 defsubr (&Sinternal__hash_table_index_size);
6253 defsubr (&Sstring_search); 6318 defsubr (&Sstring_search);
6254 defsubr (&Sobject_intervals); 6319 defsubr (&Sobject_intervals);
6255 defsubr (&Sline_number_at_pos); 6320 defsubr (&Sline_number_at_pos);