From: Paul Pogonyshev <pogonyshev@gmail.com>
To: emacs-devel@gnu.org
Subject: expose XHASH [patch]
Date: Thu, 31 Mar 2016 21:29:58 +0200 [thread overview]
Message-ID: <CAG7BparKZuRvtACRU2kPS9wyx3Yf4VgZ_LFjNZip5cGr1qkqxw@mail.gmail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 1066 bytes --]
Suppose you need a hash table with the following Lisp structures
as keys:
(NAME . [VECTOR-OF-ATTRIBUTES])
where NAME is a string. The structures are supposed to be
compared in a "mixed" way: NAME with 'equal' (or 'string='), but
VECTOR-OF-ATTRIBUTES should be compared with 'eq', i.e. by
identity.
Now, while defining test function for 'define-hash-table-test' is
not a problem, hash is problematic. While 'sxhash' _will_ work,
it is wasteful, since it computes needless information about
vector contents. Excluding vector from the hash completely is
also legal, but might considerably worsen hash table performance.
Attached trivial patch just exposes internally used XHASH(),
which fully suits this usecase. E.g. with it you could
(defun my-funny-hash (structure)
(+ (sxhash (car structure)) (* 13 (xhash (cdr structure)))))
Please don't write that the example is stupid, it is just an
example after all.
Paul
* src/fns.c (Fxhash): New function.
* doc/lispref/hash.texi (Defining Hash): Document 'xhash'.
* etc/NEWS: Mention 'xhash'.
[-- Attachment #2: xhash.diff --]
[-- Type: text/plain, Size: 2153 bytes --]
diff --git a/doc/lispref/hash.texi b/doc/lispref/hash.texi
index 8389c21..6ee18d6 100644
--- a/doc/lispref/hash.texi
+++ b/doc/lispref/hash.texi
@@ -307,6 +307,16 @@ and equal-looking objects are considered the same key.
(make-hash-table :test 'contents-hash)
@end example
+@defun xhash obj
+This function returns a hash code for Lisp object @var{obj}. Its
+result reflects identity of @var{obj}, but not its contents.
+
+If two objects @var{obj1} and @var{obj2} are @var{eq}, then
+@code{(xhash @var{obj1})} and @code{(xhash @var{obj2})} are the same
+integer.
+@end defun
+
+
@node Other Hash
@section Other Hash Table Functions
diff --git a/etc/NEWS b/etc/NEWS
index 66777e9..146c756 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -208,6 +208,12 @@ permanent and documented, and may be used by Lisp programs. Its value
is a list of currently open parenthesis positions, starting with the
outermost parenthesis.
++++
+** New function 'xhash' returns identity hash code of a Lisp object.
+If two objects are 'eq', then the result of 'xhash' on them will be
+the same. In other words, this function to 'eq' is the same as
+'sxhash' is to 'equal'.
+
\f
* Changes in Emacs 25.2 on Non-Free Operating Systems
diff --git a/src/fns.c b/src/fns.c
index 114a556..a1cf2b1 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -4449,6 +4449,16 @@ sxhash (Lisp_Object obj, int depth)
***********************************************************************/
+DEFUN ("xhash", Fxhash, Sxhash, 1, 1, 0,
+ doc: /* Compute identity hash code for OBJ and return it as integer.
+In other words, hash codes of two non-`eq' lists will be (most likely)
+different, even if the lists contain the same elements. */)
+ (Lisp_Object obj)
+{
+ return make_number (XHASH (obj));
+}
+
+
DEFUN ("sxhash", Fsxhash, Ssxhash, 1, 1, 0,
doc: /* Compute a hash code for OBJ and return it as integer. */)
(Lisp_Object obj)
@@ -5067,6 +5077,7 @@ syms_of_fns (void)
DEFSYM (Qkey_or_value, "key-or-value");
DEFSYM (Qkey_and_value, "key-and-value");
+ defsubr (&Sxhash);
defsubr (&Ssxhash);
defsubr (&Smake_hash_table);
defsubr (&Scopy_hash_table);
next reply other threads:[~2016-03-31 19:29 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-03-31 19:29 Paul Pogonyshev [this message]
2016-03-31 21:52 ` expose XHASH [patch] Stefan Monnier
2016-03-31 22:43 ` Paul Eggert
2016-04-01 9:44 ` Paul Pogonyshev
2016-04-02 11:52 ` Paul Pogonyshev
2016-04-08 16:08 ` Paul Pogonyshev
2016-04-08 18:10 ` Stefan Monnier
2016-04-08 18:37 ` Paul Pogonyshev
2016-04-08 18:44 ` Stefan Monnier
2016-04-08 19:24 ` Paul Pogonyshev
2016-04-08 20:51 ` Stefan Monnier
2016-04-08 22:37 ` Paul Eggert
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CAG7BparKZuRvtACRU2kPS9wyx3Yf4VgZ_LFjNZip5cGr1qkqxw@mail.gmail.com \
--to=pogonyshev@gmail.com \
--cc=emacs-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).