annotate src/elhash.c @ 826:6728e641994e

[xemacs-hg @ 2002-05-05 11:30:15 by ben] syntax cache, 8-bit-format, lots of code cleanup README.packages: Update info about --package-path. i.c: Create an inheritable event and pass it on to XEmacs, so that ^C can be handled properly. Intercept ^C and signal the event. "Stop Build" in VC++ now works. bytecomp-runtime.el: Doc string changes. compat.el: Some attempts to redo this to make it truly useful and fix the "multiple versions interacting with each other" problem. Not yet done. Currently doesn't work. files.el: Use with-obsolete-variable to avoid warnings in new revert-buffer code. xemacs.mak: Split up CFLAGS into a version without flags specifying the C library. The problem seems to be that minitar depends on zlib, which depends specifically on libc.lib, not on any of the other C libraries. Unless you compile with libc.lib, you get errors -- specifically, no _errno in the other libraries, which must make it something other than an int. (#### But this doesn't seem to obtain in XEmacs, which also uses zlib, and can be linked with any of the C libraries. Maybe zlib is used differently and doesn't need errno, or maybe XEmacs provides an int errno; ... I don't understand. Makefile.in.in: Fix so that packages are around when testing. abbrev.c, alloc.c, buffer.c, buffer.h, bytecode.c, callint.c, casefiddle.c, casetab.c, casetab.h, charset.h, chartab.c, chartab.h, cmds.c, console-msw.h, console-stream.c, console-x.c, console.c, console.h, data.c, device-msw.c, device.c, device.h, dialog-msw.c, dialog-x.c, dired-msw.c, dired.c, doc.c, doprnt.c, dumper.c, editfns.c, elhash.c, emacs.c, eval.c, event-Xt.c, event-gtk.c, event-msw.c, event-stream.c, events.c, events.h, extents.c, extents.h, faces.c, file-coding.c, file-coding.h, fileio.c, fns.c, font-lock.c, frame-gtk.c, frame-msw.c, frame-x.c, frame.c, frame.h, glade.c, glyphs-gtk.c, glyphs-msw.c, glyphs-msw.h, glyphs-x.c, glyphs.c, glyphs.h, gui-msw.c, gui-x.c, gui.h, gutter.h, hash.h, indent.c, insdel.c, intl-win32.c, intl.c, keymap.c, lisp-disunion.h, lisp-union.h, lisp.h, lread.c, lrecord.h, lstream.c, lstream.h, marker.c, menubar-gtk.c, menubar-msw.c, menubar-x.c, menubar.c, minibuf.c, mule-ccl.c, mule-charset.c, mule-coding.c, mule-wnnfns.c, nas.c, objects-msw.c, objects-x.c, opaque.c, postgresql.c, print.c, process-nt.c, process-unix.c, process.c, process.h, profile.c, rangetab.c, redisplay-gtk.c, redisplay-msw.c, redisplay-output.c, redisplay-x.c, redisplay.c, redisplay.h, regex.c, regex.h, scrollbar-msw.c, search.c, select-x.c, specifier.c, specifier.h, symbols.c, symsinit.h, syntax.c, syntax.h, syswindows.h, tests.c, text.c, text.h, tooltalk.c, ui-byhand.c, ui-gtk.c, unicode.c, win32.c, window.c: Another big Ben patch. -- FUNCTIONALITY CHANGES: add partial support for 8-bit-fixed, 16-bit-fixed, and 32-bit-fixed formats. not quite done yet. (in particular, needs functions to actually convert the buffer.) NOTE: lots of changes to regex.c here. also, many new *_fmt() inline funs that take an Internal_Format argument. redo syntax cache code. make the cache per-buffer; keep the cache valid across calls to functions that use it. also keep it valid across insertions/deletions and extent changes, as much as is possible. eliminate the junky regex-reentrancy code by passing in the relevant lisp info to the regex routines as local vars. add general mechanism in extents code for signalling extent changes. fix numerous problems with the case-table implementation; yoshiki never properly transferred many algorithms from old-style to new-style case tables. redo char tables to support a default argument, so that mapping only occurs over changed args. change many chartab functions to accept Lisp_Object instead of Lisp_Char_Table *. comment out the code in font-lock.c by default, because font-lock.el no longer uses it. we should consider eliminating it entirely. Don't output bell as ^G in console-stream when not a TTY. add -mswindows-termination-handle to interface with i.c, so we can properly kill a build. add more error-checking to buffer/string macros. add some additional buffer_or_string_() funs. -- INTERFACE CHANGES AFFECTING MORE CODE: switch the arguments of write_c_string and friends to be consistent with write_fmt_string, which must have printcharfun first. change BI_* macros to BYTE_* for increased clarity; similarly for bi_* local vars. change VOID_TO_LISP to be a one-argument function. eliminate no-longer-needed CVOID_TO_LISP. -- char/string macro changes: rename MAKE_CHAR() to make_emchar() for slightly less confusion with make_char(). (The former generates an Emchar, the latter a Lisp object. Conceivably we should rename make_char() -> wrap_char() and similarly for make_int(), make_float().) Similar changes for other *CHAR* macros -- we now consistently use names with `emchar' whenever we are working with Emchars. Any remaining name with just `char' always refers to a Lisp object. rename macros with XSTRING_* to string_* except for those that reference actual fields in the Lisp_String object, following conventions used elsewhere. rename set_string_{data,length} macros (the only ones to work with a Lisp_String_* instead of a Lisp_Object) to set_lispstringp_* to make the difference clear. try to be consistent about caps vs. lowercase in macro/inline-fun names for chars and such, which wasn't the case before. we now reserve caps either for XFOO_ macros that reference object fields (e.g. XSTRING_DATA) or for things that have non-function semantics, e.g. directly modifying an arg (BREAKUP_EMCHAR) or evaluating an arg (any arg) more than once. otherwise, use lowercase. here is a summary of most of the macros/inline funs changed by all of the above changes: BYTE_*_P -> byte_*_p XSTRING_BYTE -> string_byte set_string_data/length -> set_lispstringp_data/length XSTRING_CHAR_LENGTH -> string_char_length XSTRING_CHAR -> string_emchar INTBYTE_FIRST_BYTE_P -> intbyte_first_byte_p INTBYTE_LEADING_BYTE_P -> intbyte_leading_byte_p charptr_copy_char -> charptr_copy_emchar LEADING_BYTE_* -> leading_byte_* CHAR_* -> EMCHAR_* *_CHAR_* -> *_EMCHAR_* *_CHAR -> *_EMCHAR CHARSET_BY_ -> charset_by_* BYTE_SHIFT_JIS* -> byte_shift_jis* BYTE_BIG5* -> byte_big5* REP_BYTES_BY_FIRST_BYTE -> rep_bytes_by_first_byte char_to_unicode -> emchar_to_unicode valid_char_p -> valid_emchar_p Change intbyte_strcmp -> qxestrcmp_c (duplicated functionality). -- INTERFACE CHANGES AFFECTING LESS CODE: use DECLARE_INLINE_HEADER in various places. remove '#ifdef emacs' from XEmacs-only files. eliminate CHAR_TABLE_VALUE(), which duplicated the functionality of get_char_table(). add BUFFER_TEXT_LOOP to simplify iterations over buffer text. define typedefs for signed and unsigned types of fixed sizes (INT_32_BIT, UINT_32_BIT, etc.). create ALIGN_FOR_TYPE as a higher-level interface onto ALIGN_SIZE; fix code to use it. add charptr_emchar_len to return the text length of the character pointed to by a ptr; use it in place of charcount_to_bytecount(..., 1). add emchar_len to return the text length of a given character. add types Bytexpos and Charxpos to generalize Bytebpos/Bytecount and Charbpos/Charcount, in code (particularly, the extents code and redisplay code) that works with either kind of index. rename redisplay struct params with names such as `charbpos' to e.g. `charpos' when they are e.g. a Charxpos, not a Charbpos. eliminate xxDEFUN in place of DEFUN; no longer necessary with changes awhile back to doc.c. split up big ugly combined list of EXFUNs in lisp.h on a file-by-file basis, since other prototypes are similarly split. rewrite some "*_UNSAFE" macros as inline funs and eliminate the _UNSAFE suffix. move most string code from lisp.h to text.h; the string code and text.h code is now intertwined in such a fashion that they need to be in the same place and partially interleaved. (you can't create forward references for inline funs) automated/lisp-tests.el, automated/symbol-tests.el, automated/test-harness.el: Fix test harness to output FAIL messages to stderr when in batch mode. Fix up some problems in lisp-tests/symbol-tests that were causing spurious failures.
author ben
date Sun, 05 May 2002 11:33:57 +0000
parents 2b676dc88c66
children c925bacdda60
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1 /* Implementation of the hash table lisp object type.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2 Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
800
a5954632b187 [xemacs-hg @ 2002-03-31 08:27:14 by ben]
ben
parents: 793
diff changeset
3 Copyright (C) 1995, 1996, 2002 Ben Wing.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
4 Copyright (C) 1997 Free Software Foundation, Inc.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
5
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
6 This file is part of XEmacs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
7
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
8 XEmacs is free software; you can redistribute it and/or modify it
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
9 under the terms of the GNU General Public License as published by the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
10 Free Software Foundation; either version 2, or (at your option) any
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
11 later version.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
12
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
13 XEmacs is distributed in the hope that it will be useful, but WITHOUT
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
14 ANY WARRANTY; without even the implied warranty of MERCNTABILITY or
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
16 for more details.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
17
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
18 You should have received a copy of the GNU General Public License
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
19 along with XEmacs; see the file COPYING. If not, write to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
21 Boston, MA 02111-1307, USA. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
22
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
23 /* Synched up with: Not in FSF. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
24
489
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
25 /* This file implements the hash table lisp object type.
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
26
504
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
27 This implementation was mostly written by Martin Buchholz in 1997.
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
28
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
29 The Lisp-level API (derived from Common Lisp) is almost completely
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
30 compatible with GNU Emacs 21, even though the implementations are
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
31 totally independent.
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
32
489
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
33 The hash table technique used is "linear probing". Collisions are
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
34 resolved by putting the item in the next empty place in the array
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
35 following the collision. Finding a hash entry performs a linear
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
36 search in the cluster starting at the hash value.
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
37
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
38 On deletions from the hash table, the entries immediately following
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
39 the deleted entry are re-entered in the hash table. We do not have
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
40 a special way to mark deleted entries (known as "tombstones").
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
41
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
42 At the end of the hash entries ("hentries"), we leave room for an
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
43 entry that is always empty (the "sentinel").
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
44
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
45 The traditional literature on hash table implementation
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
46 (e.g. Knuth) suggests that too much "primary clustering" occurs
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
47 with linear probing. However, this literature was written when
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
48 locality of reference was not a factor. The discrepancy between
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
49 CPU speeds and memory speeds is increasing, and the speed of access
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
50 to memory is highly dependent on memory caches which work best when
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
51 there is high locality of data reference. Random access to memory
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
52 is up to 20 times as expensive as access to the nearest address
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
53 (and getting worse). So linear probing makes sense.
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
54
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
55 But the representation doesn't actually matter that much with the
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
56 current elisp engine. Funcall is sufficiently slow that the choice
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
57 of hash table implementation is noise. */
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
58
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
59 #include <config.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
60 #include "lisp.h"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
61 #include "bytecode.h"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
62 #include "elhash.h"
489
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
63 #include "opaque.h"
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
64
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
65 Lisp_Object Qhash_tablep;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
66 static Lisp_Object Qhashtable, Qhash_table;
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
67 static Lisp_Object Qweakness, Qvalue, Qkey_or_value, Qkey_and_value;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
68 static Lisp_Object Vall_weak_hash_tables;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
69 static Lisp_Object Qrehash_size, Qrehash_threshold;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
70 static Lisp_Object Q_size, Q_test, Q_weakness, Q_rehash_size, Q_rehash_threshold;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
71
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
72 /* obsolete as of 19990901 in xemacs-21.2 */
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
73 static Lisp_Object Qweak, Qkey_weak, Qvalue_weak, Qkey_or_value_weak;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
74 static Lisp_Object Qnon_weak, Q_type;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
75
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
76 typedef struct hentry
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
77 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
78 Lisp_Object key;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
79 Lisp_Object value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
80 } hentry;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
81
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
82 struct Lisp_Hash_Table
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
83 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
84 struct lcrecord_header header;
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
85 Elemcount size;
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
86 Elemcount count;
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
87 Elemcount rehash_count;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
88 double rehash_size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
89 double rehash_threshold;
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
90 Elemcount golden_ratio;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
91 hash_table_hash_function_t hash_function;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
92 hash_table_test_function_t test_function;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
93 hentry *hentries;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
94 enum hash_table_weakness weakness;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
95 Lisp_Object next_weak; /* Used to chain together all of the weak
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
96 hash tables. Don't mark through this. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
97 };
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
98
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
99 #define HENTRY_CLEAR_P(hentry) ((*(EMACS_UINT*)(&((hentry)->key))) == 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
100 #define CLEAR_HENTRY(hentry) \
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
101 ((*(EMACS_UINT*)(&((hentry)->key))) = 0, \
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
102 (*(EMACS_UINT*)(&((hentry)->value))) = 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
103
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
104 #define HASH_TABLE_DEFAULT_SIZE 16
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
105 #define HASH_TABLE_DEFAULT_REHASH_SIZE 1.3
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
106 #define HASH_TABLE_MIN_SIZE 10
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
107
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
108 #define HASHCODE(key, ht) \
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
109 ((((ht)->hash_function ? (ht)->hash_function (key) : LISP_HASH (key)) \
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
110 * (ht)->golden_ratio) \
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
111 % (ht)->size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
112
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
113 #define KEYS_EQUAL_P(key1, key2, testfun) \
434
9d177e8d4150 Import from CVS: tag r21-2-25
cvs
parents: 432
diff changeset
114 (EQ (key1, key2) || ((testfun) && (testfun) (key1, key2)))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
115
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
116 #define LINEAR_PROBING_LOOP(probe, entries, size) \
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
117 for (; \
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
118 !HENTRY_CLEAR_P (probe) || \
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
119 (probe == entries + size ? \
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
120 (probe = entries, !HENTRY_CLEAR_P (probe)) : 0); \
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
121 probe++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
122
800
a5954632b187 [xemacs-hg @ 2002-03-31 08:27:14 by ben]
ben
parents: 793
diff changeset
123 #ifdef ERROR_CHECK_STRUCTURES
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
124 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
125 check_hash_table_invariants (Lisp_Hash_Table *ht)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
126 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
127 assert (ht->count < ht->size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
128 assert (ht->count <= ht->rehash_count);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
129 assert (ht->rehash_count < ht->size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
130 assert ((double) ht->count * ht->rehash_threshold - 1 <= (double) ht->rehash_count);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
131 assert (HENTRY_CLEAR_P (ht->hentries + ht->size));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
132 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
133 #else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
134 #define check_hash_table_invariants(ht)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
135 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
136
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
137 /* Return a suitable size for a hash table, with at least SIZE slots. */
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
138 static Elemcount
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
139 hash_table_size (Elemcount requested_size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
140 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
141 /* Return some prime near, but greater than or equal to, SIZE.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
142 Decades from the time of writing, someone will have a system large
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
143 enough that the list below will be too short... */
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
144 static const Elemcount primes [] =
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
145 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
146 19, 29, 41, 59, 79, 107, 149, 197, 263, 347, 457, 599, 787, 1031,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
147 1361, 1777, 2333, 3037, 3967, 5167, 6719, 8737, 11369, 14783,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
148 19219, 24989, 32491, 42257, 54941, 71429, 92861, 120721, 156941,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
149 204047, 265271, 344857, 448321, 582821, 757693, 985003, 1280519,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
150 1664681, 2164111, 2813353, 3657361, 4754591, 6180989, 8035301,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
151 10445899, 13579681, 17653589, 22949669, 29834603, 38784989,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
152 50420551, 65546729, 85210757, 110774011, 144006217, 187208107,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
153 243370577, 316381771, 411296309, 534685237, 695090819, 903618083,
647
b39c14581166 [xemacs-hg @ 2001-08-13 04:45:47 by ben]
ben
parents: 617
diff changeset
154 1174703521, 1527114613, 1985248999 /* , 2580823717UL, 3355070839UL */
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
155 };
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
156 /* We've heard of binary search. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
157 int low, high;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
158 for (low = 0, high = countof (primes) - 1; high - low > 1;)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
159 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
160 /* Loop Invariant: size < primes [high] */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
161 int mid = (low + high) / 2;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
162 if (primes [mid] < requested_size)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
163 low = mid;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
164 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
165 high = mid;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
166 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
167 return primes [high];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
168 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
169
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
170
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
171 #if 0 /* I don't think these are needed any more.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
172 If using the general lisp_object_equal_*() functions
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
173 causes efficiency problems, these can be resurrected. --ben */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
174 /* equality and hash functions for Lisp strings */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
175 int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
176 lisp_string_equal (Lisp_Object str1, Lisp_Object str2)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
177 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
178 /* This is wrong anyway. You can't use strcmp() on Lisp strings,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
179 because they can contain zero characters. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
180 return !strcmp ((char *) XSTRING_DATA (str1), (char *) XSTRING_DATA (str2));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
181 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
182
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
183 static Hashcode
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
184 lisp_string_hash (Lisp_Object obj)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
185 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
186 return hash_string (XSTRING_DATA (str), XSTRING_LENGTH (str));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
187 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
188
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
189 #endif /* 0 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
190
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
191 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
192 lisp_object_eql_equal (Lisp_Object obj1, Lisp_Object obj2)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
193 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
194 return EQ (obj1, obj2) || (FLOATP (obj1) && internal_equal (obj1, obj2, 0));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
195 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
196
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
197 static Hashcode
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
198 lisp_object_eql_hash (Lisp_Object obj)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
199 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
200 return FLOATP (obj) ? internal_hash (obj, 0) : LISP_HASH (obj);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
201 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
202
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
203 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
204 lisp_object_equal_equal (Lisp_Object obj1, Lisp_Object obj2)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
205 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
206 return internal_equal (obj1, obj2, 0);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
207 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
208
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
209 static Hashcode
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
210 lisp_object_equal_hash (Lisp_Object obj)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
211 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
212 return internal_hash (obj, 0);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
213 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
214
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
215
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
216 static Lisp_Object
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
217 mark_hash_table (Lisp_Object obj)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
218 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
219 Lisp_Hash_Table *ht = XHASH_TABLE (obj);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
220
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
221 /* If the hash table is weak, we don't want to mark the keys and
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
222 values (we scan over them after everything else has been marked,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
223 and mark or remove them as necessary). */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
224 if (ht->weakness == HASH_TABLE_NON_WEAK)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
225 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
226 hentry *e, *sentinel;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
227
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
228 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
229 if (!HENTRY_CLEAR_P (e))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
230 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
231 mark_object (e->key);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
232 mark_object (e->value);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
233 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
234 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
235 return Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
236 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
237
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
238 /* Equality of hash tables. Two hash tables are equal when they are of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
239 the same weakness and test function, they have the same number of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
240 elements, and for each key in the hash table, the values are `equal'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
241
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
242 This is similar to Common Lisp `equalp' of hash tables, with the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
243 difference that CL requires the keys to be compared with the test
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
244 function, which we don't do. Doing that would require consing, and
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
245 consing is a bad idea in `equal'. Anyway, our method should provide
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
246 the same result -- if the keys are not equal according to the test
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
247 function, then Fgethash() in hash_table_equal_mapper() will fail. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
248 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
249 hash_table_equal (Lisp_Object hash_table1, Lisp_Object hash_table2, int depth)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
250 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
251 Lisp_Hash_Table *ht1 = XHASH_TABLE (hash_table1);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
252 Lisp_Hash_Table *ht2 = XHASH_TABLE (hash_table2);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
253 hentry *e, *sentinel;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
254
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
255 if ((ht1->test_function != ht2->test_function) ||
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
256 (ht1->weakness != ht2->weakness) ||
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
257 (ht1->count != ht2->count))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
258 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
259
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
260 depth++;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
261
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
262 for (e = ht1->hentries, sentinel = e + ht1->size; e < sentinel; e++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
263 if (!HENTRY_CLEAR_P (e))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
264 /* Look up the key in the other hash table, and compare the values. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
265 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
266 Lisp_Object value_in_other = Fgethash (e->key, hash_table2, Qunbound);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
267 if (UNBOUNDP (value_in_other) ||
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
268 !internal_equal (e->value, value_in_other, depth))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
269 return 0; /* Give up */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
270 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
271
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
272 return 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
273 }
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
274
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
275 /* This is not a great hash function, but it _is_ correct and fast.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
276 Examining all entries is too expensive, and examining a random
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
277 subset does not yield a correct hash function. */
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
278 static Hashcode
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
279 hash_table_hash (Lisp_Object hash_table, int depth)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
280 {
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
281 return XHASH_TABLE (hash_table)->count;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
282 }
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
283
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
284
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
285 /* Printing hash tables.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
286
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
287 This is non-trivial, because we use a readable structure-style
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
288 syntax for hash tables. This means that a typical hash table will be
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
289 readably printed in the form of:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
290
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
291 #s(hash-table size 2 data (key1 value1 key2 value2))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
292
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
293 The supported hash table structure keywords and their values are:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
294 `test' (eql (or nil), eq or equal)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
295 `size' (a natnum or nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
296 `rehash-size' (a float)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
297 `rehash-threshold' (a float)
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
298 `weakness' (nil, key, value, key-and-value, or key-or-value)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
299 `data' (a list)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
300
430
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
301 If `print-readably' is nil, then a simpler syntax is used, for example
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
302
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
303 #<hash-table size 2/13 data (key1 value1 key2 value2) 0x874d>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
304
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
305 The data is truncated to four pairs, and the rest is shown with
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
306 `...'. This printer does not cons. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
307
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
308
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
309 /* Print the data of the hash table. This maps through a Lisp
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
310 hash table and prints key/value pairs using PRINTCHARFUN. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
311 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
312 print_hash_table_data (Lisp_Hash_Table *ht, Lisp_Object printcharfun)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
313 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
314 int count = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
315 hentry *e, *sentinel;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
316
826
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 801
diff changeset
317 write_c_string (printcharfun, " data (");
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
318
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
319 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
320 if (!HENTRY_CLEAR_P (e))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
321 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
322 if (count > 0)
826
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 801
diff changeset
323 write_c_string (printcharfun, " ");
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
324 if (!print_readably && count > 3)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
325 {
826
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 801
diff changeset
326 write_c_string (printcharfun, "...");
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
327 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
328 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
329 print_internal (e->key, printcharfun, 1);
800
a5954632b187 [xemacs-hg @ 2002-03-31 08:27:14 by ben]
ben
parents: 793
diff changeset
330 write_fmt_string_lisp (printcharfun, " %S", 1, e->value);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
331 count++;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
332 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
333
826
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 801
diff changeset
334 write_c_string (printcharfun, ")");
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
335 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
336
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
337 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
338 print_hash_table (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
339 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
340 Lisp_Hash_Table *ht = XHASH_TABLE (obj);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
341
826
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 801
diff changeset
342 write_c_string (printcharfun,
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 801
diff changeset
343 print_readably ? "#s(hash-table" : "#<hash-table");
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
344
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
345 /* These checks have a kludgy look to them, but they are safe.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
346 Due to nature of hashing, you cannot use arbitrary
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
347 test functions anyway. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
348 if (!ht->test_function)
826
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 801
diff changeset
349 write_c_string (printcharfun, " test eq");
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
350 else if (ht->test_function == lisp_object_equal_equal)
826
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 801
diff changeset
351 write_c_string (printcharfun, " test equal");
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
352 else if (ht->test_function == lisp_object_eql_equal)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
353 DO_NOTHING;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
354 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
355 abort ();
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
356
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
357 if (ht->count || !print_readably)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
358 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
359 if (print_readably)
800
a5954632b187 [xemacs-hg @ 2002-03-31 08:27:14 by ben]
ben
parents: 793
diff changeset
360 write_fmt_string (printcharfun, " size %ld", (long) ht->count);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
361 else
800
a5954632b187 [xemacs-hg @ 2002-03-31 08:27:14 by ben]
ben
parents: 793
diff changeset
362 write_fmt_string (printcharfun, " size %ld/%ld", (long) ht->count,
a5954632b187 [xemacs-hg @ 2002-03-31 08:27:14 by ben]
ben
parents: 793
diff changeset
363 (long) ht->size);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
364 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
365
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
366 if (ht->weakness != HASH_TABLE_NON_WEAK)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
367 {
800
a5954632b187 [xemacs-hg @ 2002-03-31 08:27:14 by ben]
ben
parents: 793
diff changeset
368 write_fmt_string
a5954632b187 [xemacs-hg @ 2002-03-31 08:27:14 by ben]
ben
parents: 793
diff changeset
369 (printcharfun, " weakness %s",
a5954632b187 [xemacs-hg @ 2002-03-31 08:27:14 by ben]
ben
parents: 793
diff changeset
370 (ht->weakness == HASH_TABLE_WEAK ? "key-and-value" :
a5954632b187 [xemacs-hg @ 2002-03-31 08:27:14 by ben]
ben
parents: 793
diff changeset
371 ht->weakness == HASH_TABLE_KEY_WEAK ? "key" :
a5954632b187 [xemacs-hg @ 2002-03-31 08:27:14 by ben]
ben
parents: 793
diff changeset
372 ht->weakness == HASH_TABLE_VALUE_WEAK ? "value" :
a5954632b187 [xemacs-hg @ 2002-03-31 08:27:14 by ben]
ben
parents: 793
diff changeset
373 ht->weakness == HASH_TABLE_KEY_VALUE_WEAK ? "key-or-value" :
a5954632b187 [xemacs-hg @ 2002-03-31 08:27:14 by ben]
ben
parents: 793
diff changeset
374 "you-d-better-not-see-this"));
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
375 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
376
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
377 if (ht->count)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
378 print_hash_table_data (ht, printcharfun);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
379
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
380 if (print_readably)
826
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 801
diff changeset
381 write_c_string (printcharfun, ")");
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
382 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
383 {
800
a5954632b187 [xemacs-hg @ 2002-03-31 08:27:14 by ben]
ben
parents: 793
diff changeset
384 write_fmt_string (printcharfun, " 0x%x>", ht->header.uid);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
385 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
386 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
387
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
388 static void
489
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
389 free_hentries (hentry *hentries, size_t size)
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
390 {
800
a5954632b187 [xemacs-hg @ 2002-03-31 08:27:14 by ben]
ben
parents: 793
diff changeset
391 #ifdef ERROR_CHECK_STRUCTURES
489
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
392 /* Ensure a crash if other code uses the discarded entries afterwards. */
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
393 hentry *e, *sentinel;
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
394
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
395 for (e = hentries, sentinel = e + size; e < sentinel; e++)
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
396 * (unsigned long *) e = 0xdeadbeef;
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
397 #endif
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
398
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
399 if (!DUMPEDP (hentries))
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
400 xfree (hentries);
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
401 }
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
402
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
403 static void
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
404 finalize_hash_table (void *header, int for_disksave)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
405 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
406 if (!for_disksave)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
407 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
408 Lisp_Hash_Table *ht = (Lisp_Hash_Table *) header;
489
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
409 free_hentries (ht->hentries, ht->size);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
410 ht->hentries = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
411 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
412 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
413
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
414 static const struct lrecord_description hentry_description_1[] = {
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
415 { XD_LISP_OBJECT, offsetof (hentry, key) },
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
416 { XD_LISP_OBJECT, offsetof (hentry, value) },
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
417 { XD_END }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
418 };
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
419
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
420 static const struct struct_description hentry_description = {
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
421 sizeof (hentry),
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
422 hentry_description_1
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
423 };
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
424
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
425 const struct lrecord_description hash_table_description[] = {
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
426 { XD_ELEMCOUNT, offsetof (Lisp_Hash_Table, size) },
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
427 { XD_STRUCT_PTR, offsetof (Lisp_Hash_Table, hentries), XD_INDIRECT(0, 1), &hentry_description },
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
428 { XD_LO_LINK, offsetof (Lisp_Hash_Table, next_weak) },
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
429 { XD_END }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
430 };
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
431
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
432 DEFINE_LRECORD_IMPLEMENTATION ("hash-table", hash_table,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
433 mark_hash_table, print_hash_table,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
434 finalize_hash_table,
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
435 hash_table_equal, hash_table_hash,
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
436 hash_table_description,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
437 Lisp_Hash_Table);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
438
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
439 static Lisp_Hash_Table *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
440 xhash_table (Lisp_Object hash_table)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
441 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
442 if (!gc_in_progress)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
443 CHECK_HASH_TABLE (hash_table);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
444 check_hash_table_invariants (XHASH_TABLE (hash_table));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
445 return XHASH_TABLE (hash_table);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
446 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
447
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
448
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
449 /************************************************************************/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
450 /* Creation of Hash Tables */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
451 /************************************************************************/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
452
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
453 /* Creation of hash tables, without error-checking. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
454 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
455 compute_hash_table_derived_values (Lisp_Hash_Table *ht)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
456 {
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
457 ht->rehash_count = (Elemcount)
438
84b14dcb0985 Import from CVS: tag r21-2-27
cvs
parents: 434
diff changeset
458 ((double) ht->size * ht->rehash_threshold);
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
459 ht->golden_ratio = (Elemcount)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
460 ((double) ht->size * (.6180339887 / (double) sizeof (Lisp_Object)));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
461 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
462
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
463 Lisp_Object
450
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
464 make_standard_lisp_hash_table (enum hash_table_test test,
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
465 Elemcount size,
450
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
466 double rehash_size,
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
467 double rehash_threshold,
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
468 enum hash_table_weakness weakness)
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
469 {
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents: 458
diff changeset
470 hash_table_hash_function_t hash_function = 0;
450
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
471 hash_table_test_function_t test_function = 0;
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
472
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
473 switch (test)
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
474 {
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
475 case HASH_TABLE_EQ:
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
476 test_function = 0;
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
477 hash_function = 0;
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
478 break;
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
479
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
480 case HASH_TABLE_EQL:
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
481 test_function = lisp_object_eql_equal;
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
482 hash_function = lisp_object_eql_hash;
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
483 break;
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
484
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
485 case HASH_TABLE_EQUAL:
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
486 test_function = lisp_object_equal_equal;
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
487 hash_function = lisp_object_equal_hash;
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
488 break;
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
489
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
490 default:
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
491 abort ();
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
492 }
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
493
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
494 return make_general_lisp_hash_table (hash_function, test_function,
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
495 size, rehash_size, rehash_threshold,
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
496 weakness);
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
497 }
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
498
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
499 Lisp_Object
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
500 make_general_lisp_hash_table (hash_table_hash_function_t hash_function,
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
501 hash_table_test_function_t test_function,
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
502 Elemcount size,
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
503 double rehash_size,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
504 double rehash_threshold,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
505 enum hash_table_weakness weakness)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
506 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
507 Lisp_Object hash_table;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
508 Lisp_Hash_Table *ht = alloc_lcrecord_type (Lisp_Hash_Table, &lrecord_hash_table);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
509
450
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
510 ht->test_function = test_function;
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
511 ht->hash_function = hash_function;
438
84b14dcb0985 Import from CVS: tag r21-2-27
cvs
parents: 434
diff changeset
512 ht->weakness = weakness;
84b14dcb0985 Import from CVS: tag r21-2-27
cvs
parents: 434
diff changeset
513
84b14dcb0985 Import from CVS: tag r21-2-27
cvs
parents: 434
diff changeset
514 ht->rehash_size =
84b14dcb0985 Import from CVS: tag r21-2-27
cvs
parents: 434
diff changeset
515 rehash_size > 1.0 ? rehash_size : HASH_TABLE_DEFAULT_REHASH_SIZE;
84b14dcb0985 Import from CVS: tag r21-2-27
cvs
parents: 434
diff changeset
516
84b14dcb0985 Import from CVS: tag r21-2-27
cvs
parents: 434
diff changeset
517 ht->rehash_threshold =
84b14dcb0985 Import from CVS: tag r21-2-27
cvs
parents: 434
diff changeset
518 rehash_threshold > 0.0 ? rehash_threshold :
84b14dcb0985 Import from CVS: tag r21-2-27
cvs
parents: 434
diff changeset
519 size > 4096 && !ht->test_function ? 0.7 : 0.6;
84b14dcb0985 Import from CVS: tag r21-2-27
cvs
parents: 434
diff changeset
520
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
521 if (size < HASH_TABLE_MIN_SIZE)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
522 size = HASH_TABLE_MIN_SIZE;
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
523 ht->size = hash_table_size ((Elemcount) (((double) size / ht->rehash_threshold)
438
84b14dcb0985 Import from CVS: tag r21-2-27
cvs
parents: 434
diff changeset
524 + 1.0));
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
525 ht->count = 0;
438
84b14dcb0985 Import from CVS: tag r21-2-27
cvs
parents: 434
diff changeset
526
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
527 compute_hash_table_derived_values (ht);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
528
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
529 /* We leave room for one never-occupied sentinel hentry at the end. */
458
c33ae14dd6d0 Import from CVS: tag r21-2-44
cvs
parents: 452
diff changeset
530 ht->hentries = xnew_array_and_zero (hentry, ht->size + 1);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
531
793
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 771
diff changeset
532 hash_table = wrap_hash_table (ht);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
533
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
534 if (weakness == HASH_TABLE_NON_WEAK)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
535 ht->next_weak = Qunbound;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
536 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
537 ht->next_weak = Vall_weak_hash_tables, Vall_weak_hash_tables = hash_table;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
538
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
539 return hash_table;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
540 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
541
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
542 Lisp_Object
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
543 make_lisp_hash_table (Elemcount size,
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
544 enum hash_table_weakness weakness,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
545 enum hash_table_test test)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
546 {
450
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
547 return make_standard_lisp_hash_table (test, size, -1.0, -1.0, weakness);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
548 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
549
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
550 /* Pretty reading of hash tables.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
551
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
552 Here we use the existing structures mechanism (which is,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
553 unfortunately, pretty cumbersome) for validating and instantiating
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
554 the hash tables. The idea is that the side-effect of reading a
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
555 #s(hash-table PLIST) object is creation of a hash table with desired
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
556 properties, and that the hash table is returned. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
557
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
558 /* Validation functions: each keyword provides its own validation
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
559 function. The errors should maybe be continuable, but it is
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
560 unclear how this would cope with ERRB. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
561 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
562 hash_table_size_validate (Lisp_Object keyword, Lisp_Object value,
578
190b164ddcac [xemacs-hg @ 2001-05-25 11:26:50 by ben]
ben
parents: 563
diff changeset
563 Error_Behavior errb)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
564 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
565 if (NATNUMP (value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
566 return 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
567
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
568 maybe_signal_error_1 (Qwrong_type_argument, list2 (Qnatnump, value),
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
569 Qhash_table, errb);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
570 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
571 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
572
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
573 static Elemcount
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
574 decode_hash_table_size (Lisp_Object obj)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
575 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
576 return NILP (obj) ? HASH_TABLE_DEFAULT_SIZE : XINT (obj);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
577 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
578
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
579 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
580 hash_table_weakness_validate (Lisp_Object keyword, Lisp_Object value,
578
190b164ddcac [xemacs-hg @ 2001-05-25 11:26:50 by ben]
ben
parents: 563
diff changeset
581 Error_Behavior errb)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
582 {
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
583 if (EQ (value, Qnil)) return 1;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
584 if (EQ (value, Qt)) return 1;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
585 if (EQ (value, Qkey)) return 1;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
586 if (EQ (value, Qkey_and_value)) return 1;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
587 if (EQ (value, Qkey_or_value)) return 1;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
588 if (EQ (value, Qvalue)) return 1;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
589
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
590 /* Following values are obsolete as of 19990901 in xemacs-21.2 */
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
591 if (EQ (value, Qnon_weak)) return 1;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
592 if (EQ (value, Qweak)) return 1;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
593 if (EQ (value, Qkey_weak)) return 1;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
594 if (EQ (value, Qkey_or_value_weak)) return 1;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
595 if (EQ (value, Qvalue_weak)) return 1;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
596
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
597 maybe_invalid_constant ("Invalid hash table weakness",
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
598 value, Qhash_table, errb);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
599 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
600 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
601
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
602 static enum hash_table_weakness
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
603 decode_hash_table_weakness (Lisp_Object obj)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
604 {
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
605 if (EQ (obj, Qnil)) return HASH_TABLE_NON_WEAK;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
606 if (EQ (obj, Qt)) return HASH_TABLE_WEAK;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
607 if (EQ (obj, Qkey_and_value)) return HASH_TABLE_WEAK;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
608 if (EQ (obj, Qkey)) return HASH_TABLE_KEY_WEAK;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
609 if (EQ (obj, Qkey_or_value)) return HASH_TABLE_KEY_VALUE_WEAK;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
610 if (EQ (obj, Qvalue)) return HASH_TABLE_VALUE_WEAK;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
611
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
612 /* Following values are obsolete as of 19990901 in xemacs-21.2 */
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
613 if (EQ (obj, Qnon_weak)) return HASH_TABLE_NON_WEAK;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
614 if (EQ (obj, Qweak)) return HASH_TABLE_WEAK;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
615 if (EQ (obj, Qkey_weak)) return HASH_TABLE_KEY_WEAK;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
616 if (EQ (obj, Qkey_or_value_weak)) return HASH_TABLE_KEY_VALUE_WEAK;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
617 if (EQ (obj, Qvalue_weak)) return HASH_TABLE_VALUE_WEAK;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
618
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
619 invalid_constant ("Invalid hash table weakness", obj);
801
2b676dc88c66 [xemacs-hg @ 2002-04-01 03:58:02 by ben]
ben
parents: 800
diff changeset
620 RETURN_NOT_REACHED (HASH_TABLE_NON_WEAK)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
621 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
622
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
623 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
624 hash_table_test_validate (Lisp_Object keyword, Lisp_Object value,
578
190b164ddcac [xemacs-hg @ 2001-05-25 11:26:50 by ben]
ben
parents: 563
diff changeset
625 Error_Behavior errb)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
626 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
627 if (EQ (value, Qnil)) return 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
628 if (EQ (value, Qeq)) return 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
629 if (EQ (value, Qequal)) return 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
630 if (EQ (value, Qeql)) return 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
631
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
632 maybe_invalid_constant ("Invalid hash table test",
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
633 value, Qhash_table, errb);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
634 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
635 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
636
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
637 static enum hash_table_test
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
638 decode_hash_table_test (Lisp_Object obj)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
639 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
640 if (EQ (obj, Qnil)) return HASH_TABLE_EQL;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
641 if (EQ (obj, Qeq)) return HASH_TABLE_EQ;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
642 if (EQ (obj, Qequal)) return HASH_TABLE_EQUAL;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
643 if (EQ (obj, Qeql)) return HASH_TABLE_EQL;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
644
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
645 invalid_constant ("Invalid hash table test", obj);
801
2b676dc88c66 [xemacs-hg @ 2002-04-01 03:58:02 by ben]
ben
parents: 800
diff changeset
646 RETURN_NOT_REACHED (HASH_TABLE_EQ)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
647 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
648
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
649 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
650 hash_table_rehash_size_validate (Lisp_Object keyword, Lisp_Object value,
578
190b164ddcac [xemacs-hg @ 2001-05-25 11:26:50 by ben]
ben
parents: 563
diff changeset
651 Error_Behavior errb)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
652 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
653 if (!FLOATP (value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
654 {
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
655 maybe_signal_error_1 (Qwrong_type_argument, list2 (Qfloatp, value),
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
656 Qhash_table, errb);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
657 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
658 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
659
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
660 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
661 double rehash_size = XFLOAT_DATA (value);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
662 if (rehash_size <= 1.0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
663 {
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
664 maybe_invalid_argument
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
665 ("Hash table rehash size must be greater than 1.0",
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
666 value, Qhash_table, errb);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
667 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
668 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
669 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
670
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
671 return 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
672 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
673
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
674 static double
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
675 decode_hash_table_rehash_size (Lisp_Object rehash_size)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
676 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
677 return NILP (rehash_size) ? -1.0 : XFLOAT_DATA (rehash_size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
678 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
679
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
680 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
681 hash_table_rehash_threshold_validate (Lisp_Object keyword, Lisp_Object value,
578
190b164ddcac [xemacs-hg @ 2001-05-25 11:26:50 by ben]
ben
parents: 563
diff changeset
682 Error_Behavior errb)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
683 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
684 if (!FLOATP (value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
685 {
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
686 maybe_signal_error_1 (Qwrong_type_argument, list2 (Qfloatp, value),
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
687 Qhash_table, errb);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
688 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
689 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
690
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
691 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
692 double rehash_threshold = XFLOAT_DATA (value);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
693 if (rehash_threshold <= 0.0 || rehash_threshold >= 1.0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
694 {
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
695 maybe_invalid_argument
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
696 ("Hash table rehash threshold must be between 0.0 and 1.0",
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
697 value, Qhash_table, errb);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
698 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
699 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
700 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
701
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
702 return 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
703 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
704
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
705 static double
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
706 decode_hash_table_rehash_threshold (Lisp_Object rehash_threshold)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
707 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
708 return NILP (rehash_threshold) ? -1.0 : XFLOAT_DATA (rehash_threshold);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
709 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
710
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
711 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
712 hash_table_data_validate (Lisp_Object keyword, Lisp_Object value,
578
190b164ddcac [xemacs-hg @ 2001-05-25 11:26:50 by ben]
ben
parents: 563
diff changeset
713 Error_Behavior errb)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
714 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
715 int len;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
716
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
717 GET_EXTERNAL_LIST_LENGTH (value, len);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
718
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
719 if (len & 1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
720 {
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
721 maybe_sferror
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
722 ("Hash table data must have alternating key/value pairs",
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
723 value, Qhash_table, errb);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
724 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
725 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
726 return 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
727 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
728
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
729 /* The actual instantiation of a hash table. This does practically no
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
730 error checking, because it relies on the fact that the paranoid
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
731 functions above have error-checked everything to the last details.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
732 If this assumption is wrong, we will get a crash immediately (with
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
733 error-checking compiled in), and we'll know if there is a bug in
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
734 the structure mechanism. So there. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
735 static Lisp_Object
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
736 hash_table_instantiate (Lisp_Object plist)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
737 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
738 Lisp_Object hash_table;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
739 Lisp_Object test = Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
740 Lisp_Object size = Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
741 Lisp_Object rehash_size = Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
742 Lisp_Object rehash_threshold = Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
743 Lisp_Object weakness = Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
744 Lisp_Object data = Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
745
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
746 while (!NILP (plist))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
747 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
748 Lisp_Object key, value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
749 key = XCAR (plist); plist = XCDR (plist);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
750 value = XCAR (plist); plist = XCDR (plist);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
751
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
752 if (EQ (key, Qtest)) test = value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
753 else if (EQ (key, Qsize)) size = value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
754 else if (EQ (key, Qrehash_size)) rehash_size = value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
755 else if (EQ (key, Qrehash_threshold)) rehash_threshold = value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
756 else if (EQ (key, Qweakness)) weakness = value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
757 else if (EQ (key, Qdata)) data = value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
758 else if (EQ (key, Qtype))/*obsolete*/ weakness = value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
759 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
760 abort ();
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
761 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
762
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
763 /* Create the hash table. */
450
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
764 hash_table = make_standard_lisp_hash_table
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
765 (decode_hash_table_test (test),
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
766 decode_hash_table_size (size),
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
767 decode_hash_table_rehash_size (rehash_size),
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
768 decode_hash_table_rehash_threshold (rehash_threshold),
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
769 decode_hash_table_weakness (weakness));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
770
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
771 /* I'm not sure whether this can GC, but better safe than sorry. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
772 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
773 struct gcpro gcpro1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
774 GCPRO1 (hash_table);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
775
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
776 /* And fill it with data. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
777 while (!NILP (data))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
778 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
779 Lisp_Object key, value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
780 key = XCAR (data); data = XCDR (data);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
781 value = XCAR (data); data = XCDR (data);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
782 Fputhash (key, value, hash_table);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
783 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
784 UNGCPRO;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
785 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
786
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
787 return hash_table;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
788 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
789
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
790 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
791 structure_type_create_hash_table_structure_name (Lisp_Object structure_name)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
792 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
793 struct structure_type *st;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
794
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
795 st = define_structure_type (structure_name, 0, hash_table_instantiate);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
796 define_structure_type_keyword (st, Qtest, hash_table_test_validate);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
797 define_structure_type_keyword (st, Qsize, hash_table_size_validate);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
798 define_structure_type_keyword (st, Qrehash_size, hash_table_rehash_size_validate);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
799 define_structure_type_keyword (st, Qrehash_threshold, hash_table_rehash_threshold_validate);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
800 define_structure_type_keyword (st, Qweakness, hash_table_weakness_validate);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
801 define_structure_type_keyword (st, Qdata, hash_table_data_validate);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
802
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
803 /* obsolete as of 19990901 in xemacs-21.2 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
804 define_structure_type_keyword (st, Qtype, hash_table_weakness_validate);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
805 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
806
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
807 /* Create a built-in Lisp structure type named `hash-table'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
808 We make #s(hashtable ...) equivalent to #s(hash-table ...),
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
809 for backward compatibility.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
810 This is called from emacs.c. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
811 void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
812 structure_type_create_hash_table (void)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
813 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
814 structure_type_create_hash_table_structure_name (Qhash_table);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
815 structure_type_create_hash_table_structure_name (Qhashtable); /* compat */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
816 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
817
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
818
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
819 /************************************************************************/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
820 /* Definition of Lisp-visible methods */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
821 /************************************************************************/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
822
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
823 DEFUN ("hash-table-p", Fhash_table_p, 1, 1, 0, /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
824 Return t if OBJECT is a hash table, else nil.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
825 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
826 (object))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
827 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
828 return HASH_TABLEP (object) ? Qt : Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
829 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
830
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
831 DEFUN ("make-hash-table", Fmake_hash_table, 0, MANY, 0, /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
832 Return a new empty hash table object.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
833 Use Common Lisp style keywords to specify hash table properties.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
834 (make-hash-table &key test size rehash-size rehash-threshold weakness)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
835
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
836 Keyword :test can be `eq', `eql' (default) or `equal'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
837 Comparison between keys is done using this function.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
838 If speed is important, consider using `eq'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
839 When storing strings in the hash table, you will likely need to use `equal'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
840
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
841 Keyword :size specifies the number of keys likely to be inserted.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
842 This number of entries can be inserted without enlarging the hash table.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
843
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
844 Keyword :rehash-size must be a float greater than 1.0, and specifies
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
845 the factor by which to increase the size of the hash table when enlarging.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
846
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
847 Keyword :rehash-threshold must be a float between 0.0 and 1.0,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
848 and specifies the load factor of the hash table which triggers enlarging.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
849
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
850 Non-standard keyword :weakness can be `nil' (default), `t', `key-and-value',
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
851 `key', `value' or `key-or-value'. `t' is an alias for `key-and-value'.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
852
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
853 A key-and-value-weak hash table, also known as a fully-weak or simply
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
854 as a weak hash table, is one whose pointers do not count as GC
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
855 referents: for any key-value pair in the hash table, if the only
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
856 remaining pointer to either the key or the value is in a weak hash
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
857 table, then the pair will be removed from the hash table, and the key
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
858 and value collected. A non-weak hash table (or any other pointer)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
859 would prevent the object from being collected.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
860
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
861 A key-weak hash table is similar to a fully-weak hash table except that
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
862 a key-value pair will be removed only if the key remains unmarked
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
863 outside of weak hash tables. The pair will remain in the hash table if
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
864 the key is pointed to by something other than a weak hash table, even
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
865 if the value is not.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
866
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
867 A value-weak hash table is similar to a fully-weak hash table except
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
868 that a key-value pair will be removed only if the value remains
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
869 unmarked outside of weak hash tables. The pair will remain in the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
870 hash table if the value is pointed to by something other than a weak
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
871 hash table, even if the key is not.
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
872
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
873 A key-or-value-weak hash table is similar to a fully-weak hash table except
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
874 that a key-value pair will be removed only if the value and the key remain
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
875 unmarked outside of weak hash tables. The pair will remain in the
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
876 hash table if the value or key are pointed to by something other than a weak
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
877 hash table, even if the other is not.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
878 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
879 (int nargs, Lisp_Object *args))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
880 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
881 int i = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
882 Lisp_Object test = Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
883 Lisp_Object size = Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
884 Lisp_Object rehash_size = Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
885 Lisp_Object rehash_threshold = Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
886 Lisp_Object weakness = Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
887
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
888 while (i + 1 < nargs)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
889 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
890 Lisp_Object keyword = args[i++];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
891 Lisp_Object value = args[i++];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
892
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
893 if (EQ (keyword, Q_test)) test = value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
894 else if (EQ (keyword, Q_size)) size = value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
895 else if (EQ (keyword, Q_rehash_size)) rehash_size = value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
896 else if (EQ (keyword, Q_rehash_threshold)) rehash_threshold = value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
897 else if (EQ (keyword, Q_weakness)) weakness = value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
898 else if (EQ (keyword, Q_type))/*obsolete*/ weakness = value;
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
899 else invalid_constant ("Invalid hash table property keyword", keyword);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
900 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
901
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
902 if (i < nargs)
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
903 sferror ("Hash table property requires a value", args[i]);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
904
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
905 #define VALIDATE_VAR(var) \
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
906 if (!NILP (var)) hash_table_##var##_validate (Q##var, var, ERROR_ME);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
907
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
908 VALIDATE_VAR (test);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
909 VALIDATE_VAR (size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
910 VALIDATE_VAR (rehash_size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
911 VALIDATE_VAR (rehash_threshold);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
912 VALIDATE_VAR (weakness);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
913
450
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
914 return make_standard_lisp_hash_table
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
915 (decode_hash_table_test (test),
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
916 decode_hash_table_size (size),
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
917 decode_hash_table_rehash_size (rehash_size),
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
918 decode_hash_table_rehash_threshold (rehash_threshold),
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
919 decode_hash_table_weakness (weakness));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
920 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
921
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
922 DEFUN ("copy-hash-table", Fcopy_hash_table, 1, 1, 0, /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
923 Return a new hash table containing the same keys and values as HASH-TABLE.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
924 The keys and values will not themselves be copied.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
925 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
926 (hash_table))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
927 {
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
928 const Lisp_Hash_Table *ht_old = xhash_table (hash_table);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
929 Lisp_Hash_Table *ht = alloc_lcrecord_type (Lisp_Hash_Table, &lrecord_hash_table);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
930
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
931 copy_lcrecord (ht, ht_old);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
932
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
933 ht->hentries = xnew_array (hentry, ht_old->size + 1);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
934 memcpy (ht->hentries, ht_old->hentries, (ht_old->size + 1) * sizeof (hentry));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
935
793
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 771
diff changeset
936 hash_table = wrap_hash_table (ht);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
937
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
938 if (! EQ (ht->next_weak, Qunbound))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
939 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
940 ht->next_weak = Vall_weak_hash_tables;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
941 Vall_weak_hash_tables = hash_table;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
942 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
943
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
944 return hash_table;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
945 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
946
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
947 static void
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
948 resize_hash_table (Lisp_Hash_Table *ht, Elemcount new_size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
949 {
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
950 hentry *old_entries, *new_entries, *sentinel, *e;
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
951 Elemcount old_size;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
952
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
953 old_size = ht->size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
954 ht->size = new_size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
955
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
956 old_entries = ht->hentries;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
957
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
958 ht->hentries = xnew_array_and_zero (hentry, new_size + 1);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
959 new_entries = ht->hentries;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
960
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
961 compute_hash_table_derived_values (ht);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
962
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
963 for (e = old_entries, sentinel = e + old_size; e < sentinel; e++)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
964 if (!HENTRY_CLEAR_P (e))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
965 {
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
966 hentry *probe = new_entries + HASHCODE (e->key, ht);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
967 LINEAR_PROBING_LOOP (probe, new_entries, new_size)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
968 ;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
969 *probe = *e;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
970 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
971
489
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
972 free_hentries (old_entries, old_size);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
973 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
974
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
975 /* After a hash table has been saved to disk and later restored by the
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
976 portable dumper, it contains the same objects, but their addresses
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
977 and thus their HASHCODEs have changed. */
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
978 void
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
979 pdump_reorganize_hash_table (Lisp_Object hash_table)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
980 {
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
981 const Lisp_Hash_Table *ht = xhash_table (hash_table);
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
982 hentry *new_entries = xnew_array_and_zero (hentry, ht->size + 1);
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
983 hentry *e, *sentinel;
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
984
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
985 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
986 if (!HENTRY_CLEAR_P (e))
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
987 {
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
988 hentry *probe = new_entries + HASHCODE (e->key, ht);
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
989 LINEAR_PROBING_LOOP (probe, new_entries, ht->size)
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
990 ;
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
991 *probe = *e;
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
992 }
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
993
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
994 memcpy (ht->hentries, new_entries, ht->size * sizeof (hentry));
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
995
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
996 xfree (new_entries);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
997 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
998
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
999 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1000 enlarge_hash_table (Lisp_Hash_Table *ht)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1001 {
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1002 Elemcount new_size =
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1003 hash_table_size ((Elemcount) ((double) ht->size * ht->rehash_size));
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1004 resize_hash_table (ht, new_size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1005 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1006
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1007 static hentry *
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1008 find_hentry (Lisp_Object key, const Lisp_Hash_Table *ht)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1009 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1010 hash_table_test_function_t test_function = ht->test_function;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1011 hentry *entries = ht->hentries;
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1012 hentry *probe = entries + HASHCODE (key, ht);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1013
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1014 LINEAR_PROBING_LOOP (probe, entries, ht->size)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1015 if (KEYS_EQUAL_P (probe->key, key, test_function))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1016 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1017
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1018 return probe;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1019 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1020
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1021 DEFUN ("gethash", Fgethash, 2, 3, 0, /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1022 Find hash value for KEY in HASH-TABLE.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1023 If there is no corresponding value, return DEFAULT (which defaults to nil).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1024 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1025 (key, hash_table, default_))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1026 {
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1027 const Lisp_Hash_Table *ht = xhash_table (hash_table);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1028 hentry *e = find_hentry (key, ht);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1029
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1030 return HENTRY_CLEAR_P (e) ? default_ : e->value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1031 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1032
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1033 DEFUN ("puthash", Fputhash, 3, 3, 0, /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1034 Hash KEY to VALUE in HASH-TABLE.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1035 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1036 (key, value, hash_table))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1037 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1038 Lisp_Hash_Table *ht = xhash_table (hash_table);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1039 hentry *e = find_hentry (key, ht);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1040
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1041 if (!HENTRY_CLEAR_P (e))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1042 return e->value = value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1043
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1044 e->key = key;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1045 e->value = value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1046
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1047 if (++ht->count >= ht->rehash_count)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1048 enlarge_hash_table (ht);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1049
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1050 return value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1051 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1052
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1053 /* Remove hentry pointed at by PROBE.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1054 Subsequent entries are removed and reinserted.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1055 We don't use tombstones - too wasteful. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1056 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1057 remhash_1 (Lisp_Hash_Table *ht, hentry *entries, hentry *probe)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1058 {
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1059 Elemcount size = ht->size;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1060 CLEAR_HENTRY (probe);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1061 probe++;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1062 ht->count--;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1063
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1064 LINEAR_PROBING_LOOP (probe, entries, size)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1065 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1066 Lisp_Object key = probe->key;
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1067 hentry *probe2 = entries + HASHCODE (key, ht);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1068 LINEAR_PROBING_LOOP (probe2, entries, size)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1069 if (EQ (probe2->key, key))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1070 /* hentry at probe doesn't need to move. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1071 goto continue_outer_loop;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1072 /* Move hentry from probe to new home at probe2. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1073 *probe2 = *probe;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1074 CLEAR_HENTRY (probe);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1075 continue_outer_loop: continue;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1076 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1077 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1078
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1079 DEFUN ("remhash", Fremhash, 2, 2, 0, /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1080 Remove the entry for KEY from HASH-TABLE.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1081 Do nothing if there is no entry for KEY in HASH-TABLE.
617
af57a77cbc92 [xemacs-hg @ 2001-06-18 07:09:50 by ben]
ben
parents: 578
diff changeset
1082 Return non-nil if an entry was removed.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1083 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1084 (key, hash_table))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1085 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1086 Lisp_Hash_Table *ht = xhash_table (hash_table);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1087 hentry *e = find_hentry (key, ht);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1088
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1089 if (HENTRY_CLEAR_P (e))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1090 return Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1091
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1092 remhash_1 (ht, ht->hentries, e);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1093 return Qt;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1094 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1095
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1096 DEFUN ("clrhash", Fclrhash, 1, 1, 0, /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1097 Remove all entries from HASH-TABLE, leaving it empty.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1098 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1099 (hash_table))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1100 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1101 Lisp_Hash_Table *ht = xhash_table (hash_table);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1102 hentry *e, *sentinel;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1103
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1104 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1105 CLEAR_HENTRY (e);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1106 ht->count = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1107
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1108 return hash_table;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1109 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1110
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1111 /************************************************************************/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1112 /* Accessor Functions */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1113 /************************************************************************/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1114
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1115 DEFUN ("hash-table-count", Fhash_table_count, 1, 1, 0, /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1116 Return the number of entries in HASH-TABLE.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1117 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1118 (hash_table))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1119 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1120 return make_int (xhash_table (hash_table)->count);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1121 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1122
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1123 DEFUN ("hash-table-test", Fhash_table_test, 1, 1, 0, /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1124 Return the test function of HASH-TABLE.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1125 This can be one of `eq', `eql' or `equal'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1126 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1127 (hash_table))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1128 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1129 hash_table_test_function_t fun = xhash_table (hash_table)->test_function;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1130
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1131 return (fun == lisp_object_eql_equal ? Qeql :
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1132 fun == lisp_object_equal_equal ? Qequal :
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1133 Qeq);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1134 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1135
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1136 DEFUN ("hash-table-size", Fhash_table_size, 1, 1, 0, /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1137 Return the size of HASH-TABLE.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1138 This is the current number of slots in HASH-TABLE, whether occupied or not.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1139 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1140 (hash_table))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1141 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1142 return make_int (xhash_table (hash_table)->size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1143 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1144
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1145 DEFUN ("hash-table-rehash-size", Fhash_table_rehash_size, 1, 1, 0, /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1146 Return the current rehash size of HASH-TABLE.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1147 This is a float greater than 1.0; the factor by which HASH-TABLE
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1148 is enlarged when the rehash threshold is exceeded.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1149 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1150 (hash_table))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1151 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1152 return make_float (xhash_table (hash_table)->rehash_size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1153 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1154
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1155 DEFUN ("hash-table-rehash-threshold", Fhash_table_rehash_threshold, 1, 1, 0, /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1156 Return the current rehash threshold of HASH-TABLE.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1157 This is a float between 0.0 and 1.0; the maximum `load factor' of HASH-TABLE,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1158 beyond which the HASH-TABLE is enlarged by rehashing.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1159 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1160 (hash_table))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1161 {
438
84b14dcb0985 Import from CVS: tag r21-2-27
cvs
parents: 434
diff changeset
1162 return make_float (xhash_table (hash_table)->rehash_threshold);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1163 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1164
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1165 DEFUN ("hash-table-weakness", Fhash_table_weakness, 1, 1, 0, /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1166 Return the weakness of HASH-TABLE.
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1167 This can be one of `nil', `key-and-value', `key-or-value', `key' or `value'.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1168 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1169 (hash_table))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1170 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1171 switch (xhash_table (hash_table)->weakness)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1172 {
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1173 case HASH_TABLE_WEAK: return Qkey_and_value;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1174 case HASH_TABLE_KEY_WEAK: return Qkey;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1175 case HASH_TABLE_KEY_VALUE_WEAK: return Qkey_or_value;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1176 case HASH_TABLE_VALUE_WEAK: return Qvalue;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1177 default: return Qnil;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1178 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1179 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1180
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1181 /* obsolete as of 19990901 in xemacs-21.2 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1182 DEFUN ("hash-table-type", Fhash_table_type, 1, 1, 0, /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1183 Return the type of HASH-TABLE.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1184 This can be one of `non-weak', `weak', `key-weak' or `value-weak'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1185 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1186 (hash_table))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1187 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1188 switch (xhash_table (hash_table)->weakness)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1189 {
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1190 case HASH_TABLE_WEAK: return Qweak;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1191 case HASH_TABLE_KEY_WEAK: return Qkey_weak;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1192 case HASH_TABLE_KEY_VALUE_WEAK: return Qkey_or_value_weak;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1193 case HASH_TABLE_VALUE_WEAK: return Qvalue_weak;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1194 default: return Qnon_weak;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1195 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1196 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1197
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1198 /************************************************************************/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1199 /* Mapping Functions */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1200 /************************************************************************/
489
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1201
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1202 /* We need to be careful when mapping over hash tables because the
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1203 hash table might be modified during the mapping operation:
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1204 - by the mapping function
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1205 - by gc (if the hash table is weak)
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1206
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1207 So we make a copy of the hentries at the beginning of the mapping
497
11b53bb7daf5 [xemacs-hg @ 2001-05-02 10:22:58 by martinb]
martinb
parents: 489
diff changeset
1208 operation, and iterate over the copy. Naturally, this is
11b53bb7daf5 [xemacs-hg @ 2001-05-02 10:22:58 by martinb]
martinb
parents: 489
diff changeset
1209 expensive, but not as expensive as you might think, because no
11b53bb7daf5 [xemacs-hg @ 2001-05-02 10:22:58 by martinb]
martinb
parents: 489
diff changeset
1210 actual memory has to be collected by our notoriously inefficient
11b53bb7daf5 [xemacs-hg @ 2001-05-02 10:22:58 by martinb]
martinb
parents: 489
diff changeset
1211 GC; we use an unwind-protect instead to free the memory directly.
11b53bb7daf5 [xemacs-hg @ 2001-05-02 10:22:58 by martinb]
martinb
parents: 489
diff changeset
1212
11b53bb7daf5 [xemacs-hg @ 2001-05-02 10:22:58 by martinb]
martinb
parents: 489
diff changeset
1213 We could avoid the copying by having the hash table modifiers
11b53bb7daf5 [xemacs-hg @ 2001-05-02 10:22:58 by martinb]
martinb
parents: 489
diff changeset
1214 puthash and remhash check for currently active mapping functions.
11b53bb7daf5 [xemacs-hg @ 2001-05-02 10:22:58 by martinb]
martinb
parents: 489
diff changeset
1215 Disadvantages: it's hard to get right, and IMO hash mapping
11b53bb7daf5 [xemacs-hg @ 2001-05-02 10:22:58 by martinb]
martinb
parents: 489
diff changeset
1216 functions are basically rare, and no extra space in the hash table
11b53bb7daf5 [xemacs-hg @ 2001-05-02 10:22:58 by martinb]
martinb
parents: 489
diff changeset
1217 object and no extra cpu in puthash or remhash should be wasted to
11b53bb7daf5 [xemacs-hg @ 2001-05-02 10:22:58 by martinb]
martinb
parents: 489
diff changeset
1218 make maphash 3% faster. From a design point of view, the basic
11b53bb7daf5 [xemacs-hg @ 2001-05-02 10:22:58 by martinb]
martinb
parents: 489
diff changeset
1219 functions gethash, puthash and remhash should be implementable
11b53bb7daf5 [xemacs-hg @ 2001-05-02 10:22:58 by martinb]
martinb
parents: 489
diff changeset
1220 without having to think about maphash.
11b53bb7daf5 [xemacs-hg @ 2001-05-02 10:22:58 by martinb]
martinb
parents: 489
diff changeset
1221
11b53bb7daf5 [xemacs-hg @ 2001-05-02 10:22:58 by martinb]
martinb
parents: 489
diff changeset
1222 Note: We don't (yet) have Common Lisp's with-hash-table-iterator.
11b53bb7daf5 [xemacs-hg @ 2001-05-02 10:22:58 by martinb]
martinb
parents: 489
diff changeset
1223 If you implement this naively, you cannot have more than one
11b53bb7daf5 [xemacs-hg @ 2001-05-02 10:22:58 by martinb]
martinb
parents: 489
diff changeset
1224 concurrently active iterator over the same hash table. The `each'
11b53bb7daf5 [xemacs-hg @ 2001-05-02 10:22:58 by martinb]
martinb
parents: 489
diff changeset
1225 function in perl has this limitation.
11b53bb7daf5 [xemacs-hg @ 2001-05-02 10:22:58 by martinb]
martinb
parents: 489
diff changeset
1226
11b53bb7daf5 [xemacs-hg @ 2001-05-02 10:22:58 by martinb]
martinb
parents: 489
diff changeset
1227 Note: We GCPRO memory on the heap, not on the stack. There is no
11b53bb7daf5 [xemacs-hg @ 2001-05-02 10:22:58 by martinb]
martinb
parents: 489
diff changeset
1228 obvious reason why this is bad, but as of this writing this is the
11b53bb7daf5 [xemacs-hg @ 2001-05-02 10:22:58 by martinb]
martinb
parents: 489
diff changeset
1229 only known occurrence of this technique in the code.
504
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
1230
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
1231 -- Martin
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
1232 */
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
1233
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
1234 /* Ben disagrees with the "copying hentries" design, and says:
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
1235
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
1236 Another solution is the same as I've already proposed -- when
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
1237 mapping, mark the table as "change-unsafe", and in this case, use a
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
1238 secondary table to maintain changes. this could be basically a
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
1239 standard hash table, but with entries only for added or deleted
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
1240 entries in the primary table, and a marker like Qunbound to
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
1241 indicate a deleted entry. puthash, gethash and remhash need a
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
1242 single extra check for this secondary table -- totally
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
1243 insignificant speedwise. if you really cared about making
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
1244 recursive maphashes completely correct, you'd have to do a bit of
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
1245 extra work here -- when maphashing, if the secondary table exists,
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
1246 make a copy of it, and use the copy in conjunction with the primary
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
1247 table when mapping. the advantages of this are
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
1248
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
1249 [a] easy to demonstrate correct, even with weak hashtables.
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
1250
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
1251 [b] no extra overhead in the general maphash case -- only when you
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
1252 modify the table while maphashing, and even then the overhead is
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
1253 very small.
497
11b53bb7daf5 [xemacs-hg @ 2001-05-02 10:22:58 by martinb]
martinb
parents: 489
diff changeset
1254 */
11b53bb7daf5 [xemacs-hg @ 2001-05-02 10:22:58 by martinb]
martinb
parents: 489
diff changeset
1255
489
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1256 static Lisp_Object
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1257 maphash_unwind (Lisp_Object unwind_obj)
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1258 {
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1259 void *ptr = (void *) get_opaque_ptr (unwind_obj);
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1260 xfree (ptr);
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1261 free_opaque_ptr (unwind_obj);
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1262 return Qnil;
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1263 }
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1264
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1265 /* Return a malloced array of alternating key/value pairs from HT. */
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1266 static Lisp_Object *
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1267 copy_compress_hentries (const Lisp_Hash_Table *ht)
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1268 {
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1269 Lisp_Object * const objs =
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1270 /* If the hash table is empty, ht->count could be 0. */
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1271 xnew_array (Lisp_Object, 2 * (ht->count > 0 ? ht->count : 1));
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1272 const hentry *e, *sentinel;
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1273 Lisp_Object *pobj;
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1274
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1275 for (e = ht->hentries, sentinel = e + ht->size, pobj = objs; e < sentinel; e++)
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1276 if (!HENTRY_CLEAR_P (e))
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1277 {
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1278 *(pobj++) = e->key;
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1279 *(pobj++) = e->value;
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1280 }
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1281
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1282 type_checking_assert (pobj == objs + 2 * ht->count);
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1283
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1284 return objs;
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1285 }
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1286
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1287 DEFUN ("maphash", Fmaphash, 2, 2, 0, /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1288 Map FUNCTION over entries in HASH-TABLE, calling it with two args,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1289 each key and value in HASH-TABLE.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1290
489
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1291 FUNCTION must not modify HASH-TABLE, with the one exception that FUNCTION
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1292 may remhash or puthash the entry currently being processed by FUNCTION.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1293 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1294 (function, hash_table))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1295 {
489
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1296 const Lisp_Hash_Table * const ht = xhash_table (hash_table);
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1297 Lisp_Object * const objs = copy_compress_hentries (ht);
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1298 Lisp_Object args[3];
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1299 const Lisp_Object *pobj, *end;
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1300 int speccount = specpdl_depth ();
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1301 struct gcpro gcpro1;
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1302
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1303 record_unwind_protect (maphash_unwind, make_opaque_ptr ((void *)objs));
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1304 GCPRO1 (objs[0]);
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1305 gcpro1.nvars = 2 * ht->count;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1306
489
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1307 args[0] = function;
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1308
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1309 for (pobj = objs, end = pobj + 2 * ht->count; pobj < end; pobj += 2)
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1310 {
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1311 args[1] = pobj[0];
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1312 args[2] = pobj[1];
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1313 Ffuncall (countof (args), args);
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1314 }
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1315
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
1316 unbind_to (speccount);
489
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1317 UNGCPRO;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1318
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1319 return Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1320 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1321
489
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1322 /* Map *C* function FUNCTION over the elements of a non-weak lisp hash table.
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1323 FUNCTION must not modify HASH-TABLE, with the one exception that FUNCTION
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1324 may puthash the entry currently being processed by FUNCTION.
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1325 Mapping terminates if FUNCTION returns something other than 0. */
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1326 void
489
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1327 elisp_maphash_unsafe (maphash_function_t function,
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1328 Lisp_Object hash_table, void *extra_arg)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1329 {
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1330 const Lisp_Hash_Table *ht = XHASH_TABLE (hash_table);
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1331 const hentry *e, *sentinel;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1332
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1333 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1334 if (!HENTRY_CLEAR_P (e))
489
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1335 if (function (e->key, e->value, extra_arg))
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1336 return;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1337 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1338
489
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1339 /* Map *C* function FUNCTION over the elements of a lisp hash table.
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1340 It is safe for FUNCTION to modify HASH-TABLE.
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1341 Mapping terminates if FUNCTION returns something other than 0. */
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1342 void
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1343 elisp_maphash (maphash_function_t function,
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1344 Lisp_Object hash_table, void *extra_arg)
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1345 {
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1346 const Lisp_Hash_Table * const ht = xhash_table (hash_table);
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1347 Lisp_Object * const objs = copy_compress_hentries (ht);
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1348 const Lisp_Object *pobj, *end;
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1349 int speccount = specpdl_depth ();
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1350 struct gcpro gcpro1;
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1351
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1352 record_unwind_protect (maphash_unwind, make_opaque_ptr ((void *)objs));
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1353 GCPRO1 (objs[0]);
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1354 gcpro1.nvars = 2 * ht->count;
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1355
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1356 for (pobj = objs, end = pobj + 2 * ht->count; pobj < end; pobj += 2)
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1357 if (function (pobj[0], pobj[1], extra_arg))
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1358 break;
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1359
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
1360 unbind_to (speccount);
489
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1361 UNGCPRO;
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1362 }
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1363
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1364 /* Remove all elements of a lisp hash table satisfying *C* predicate PREDICATE.
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1365 PREDICATE must not modify HASH-TABLE. */
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1366 void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1367 elisp_map_remhash (maphash_function_t predicate,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1368 Lisp_Object hash_table, void *extra_arg)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1369 {
489
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1370 const Lisp_Hash_Table * const ht = xhash_table (hash_table);
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1371 Lisp_Object * const objs = copy_compress_hentries (ht);
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1372 const Lisp_Object *pobj, *end;
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1373 int speccount = specpdl_depth ();
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1374 struct gcpro gcpro1;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1375
489
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1376 record_unwind_protect (maphash_unwind, make_opaque_ptr ((void *)objs));
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1377 GCPRO1 (objs[0]);
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1378 gcpro1.nvars = 2 * ht->count;
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1379
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1380 for (pobj = objs, end = pobj + 2 * ht->count; pobj < end; pobj += 2)
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1381 if (predicate (pobj[0], pobj[1], extra_arg))
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1382 Fremhash (pobj[0], hash_table);
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1383
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
1384 unbind_to (speccount);
489
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1385 UNGCPRO;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1386 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1387
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1388
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1389 /************************************************************************/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1390 /* garbage collecting weak hash tables */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1391 /************************************************************************/
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1392 #define MARK_OBJ(obj) do { \
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1393 Lisp_Object mo_obj = (obj); \
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1394 if (!marked_p (mo_obj)) \
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1395 { \
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1396 mark_object (mo_obj); \
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1397 did_mark = 1; \
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1398 } \
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1399 } while (0)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1400
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1401
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1402 /* Complete the marking for semi-weak hash tables. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1403 int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1404 finish_marking_weak_hash_tables (void)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1405 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1406 Lisp_Object hash_table;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1407 int did_mark = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1408
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1409 for (hash_table = Vall_weak_hash_tables;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1410 !NILP (hash_table);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1411 hash_table = XHASH_TABLE (hash_table)->next_weak)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1412 {
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1413 const Lisp_Hash_Table *ht = XHASH_TABLE (hash_table);
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1414 const hentry *e = ht->hentries;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1415 const hentry *sentinel = e + ht->size;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1416
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1417 if (! marked_p (hash_table))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1418 /* The hash table is probably garbage. Ignore it. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1419 continue;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1420
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1421 /* Now, scan over all the pairs. For all pairs that are
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1422 half-marked, we may need to mark the other half if we're
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1423 keeping this pair. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1424 switch (ht->weakness)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1425 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1426 case HASH_TABLE_KEY_WEAK:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1427 for (; e < sentinel; e++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1428 if (!HENTRY_CLEAR_P (e))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1429 if (marked_p (e->key))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1430 MARK_OBJ (e->value);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1431 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1432
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1433 case HASH_TABLE_VALUE_WEAK:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1434 for (; e < sentinel; e++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1435 if (!HENTRY_CLEAR_P (e))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1436 if (marked_p (e->value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1437 MARK_OBJ (e->key);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1438 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1439
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1440 case HASH_TABLE_KEY_VALUE_WEAK:
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1441 for (; e < sentinel; e++)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1442 if (!HENTRY_CLEAR_P (e))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1443 {
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1444 if (marked_p (e->value))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1445 MARK_OBJ (e->key);
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1446 else if (marked_p (e->key))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1447 MARK_OBJ (e->value);
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1448 }
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1449 break;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1450
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1451 case HASH_TABLE_KEY_CAR_WEAK:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1452 for (; e < sentinel; e++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1453 if (!HENTRY_CLEAR_P (e))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1454 if (!CONSP (e->key) || marked_p (XCAR (e->key)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1455 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1456 MARK_OBJ (e->key);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1457 MARK_OBJ (e->value);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1458 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1459 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1460
450
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
1461 /* We seem to be sprouting new weakness types at an alarming
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
1462 rate. At least this is not externally visible - and in
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
1463 fact all of these KEY_CAR_* types are only used by the
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
1464 glyph code. */
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
1465 case HASH_TABLE_KEY_CAR_VALUE_WEAK:
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
1466 for (; e < sentinel; e++)
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
1467 if (!HENTRY_CLEAR_P (e))
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
1468 {
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
1469 if (!CONSP (e->key) || marked_p (XCAR (e->key)))
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
1470 {
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
1471 MARK_OBJ (e->key);
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
1472 MARK_OBJ (e->value);
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
1473 }
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
1474 else if (marked_p (e->value))
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
1475 MARK_OBJ (e->key);
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
1476 }
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
1477 break;
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
1478
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1479 case HASH_TABLE_VALUE_CAR_WEAK:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1480 for (; e < sentinel; e++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1481 if (!HENTRY_CLEAR_P (e))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1482 if (!CONSP (e->value) || marked_p (XCAR (e->value)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1483 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1484 MARK_OBJ (e->key);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1485 MARK_OBJ (e->value);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1486 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1487 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1488
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1489 default:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1490 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1491 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1492 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1493
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1494 return did_mark;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1495 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1496
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1497 void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1498 prune_weak_hash_tables (void)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1499 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1500 Lisp_Object hash_table, prev = Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1501 for (hash_table = Vall_weak_hash_tables;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1502 !NILP (hash_table);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1503 hash_table = XHASH_TABLE (hash_table)->next_weak)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1504 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1505 if (! marked_p (hash_table))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1506 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1507 /* This hash table itself is garbage. Remove it from the list. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1508 if (NILP (prev))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1509 Vall_weak_hash_tables = XHASH_TABLE (hash_table)->next_weak;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1510 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1511 XHASH_TABLE (prev)->next_weak = XHASH_TABLE (hash_table)->next_weak;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1512 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1513 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1514 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1515 /* Now, scan over all the pairs. Remove all of the pairs
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1516 in which the key or value, or both, is unmarked
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1517 (depending on the weakness of the hash table). */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1518 Lisp_Hash_Table *ht = XHASH_TABLE (hash_table);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1519 hentry *entries = ht->hentries;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1520 hentry *sentinel = entries + ht->size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1521 hentry *e;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1522
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1523 for (e = entries; e < sentinel; e++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1524 if (!HENTRY_CLEAR_P (e))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1525 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1526 again:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1527 if (!marked_p (e->key) || !marked_p (e->value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1528 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1529 remhash_1 (ht, entries, e);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1530 if (!HENTRY_CLEAR_P (e))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1531 goto again;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1532 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1533 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1534
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1535 prev = hash_table;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1536 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1537 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1538 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1539
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1540 /* Return a hash value for an array of Lisp_Objects of size SIZE. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1541
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1542 Hashcode
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1543 internal_array_hash (Lisp_Object *arr, int size, int depth)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1544 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1545 int i;
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1546 Hashcode hash = 0;
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1547 depth++;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1548
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1549 if (size <= 5)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1550 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1551 for (i = 0; i < size; i++)
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1552 hash = HASH2 (hash, internal_hash (arr[i], depth));
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1553 return hash;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1554 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1555
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1556 /* just pick five elements scattered throughout the array.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1557 A slightly better approach would be to offset by some
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1558 noise factor from the points chosen below. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1559 for (i = 0; i < 5; i++)
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1560 hash = HASH2 (hash, internal_hash (arr[i*size/5], depth));
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1561
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1562 return hash;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1563 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1564
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1565 /* Return a hash value for a Lisp_Object. This is for use when hashing
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1566 objects with the comparison being `equal' (for `eq', you can just
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1567 use the Lisp_Object itself as the hash value). You need to make a
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1568 tradeoff between the speed of the hash function and how good the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1569 hashing is. In particular, the hash function needs to be FAST,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1570 so you can't just traipse down the whole tree hashing everything
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1571 together. Most of the time, objects will differ in the first
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1572 few elements you hash. Thus, we only go to a short depth (5)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1573 and only hash at most 5 elements out of a vector. Theoretically
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1574 we could still take 5^5 time (a big big number) to compute a
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1575 hash, but practically this won't ever happen. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1576
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1577 Hashcode
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1578 internal_hash (Lisp_Object obj, int depth)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1579 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1580 if (depth > 5)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1581 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1582 if (CONSP (obj))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1583 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1584 /* no point in worrying about tail recursion, since we're not
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1585 going very deep */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1586 return HASH2 (internal_hash (XCAR (obj), depth + 1),
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1587 internal_hash (XCDR (obj), depth + 1));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1588 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1589 if (STRINGP (obj))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1590 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1591 return hash_string (XSTRING_DATA (obj), XSTRING_LENGTH (obj));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1592 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1593 if (LRECORDP (obj))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1594 {
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1595 const struct lrecord_implementation
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1596 *imp = XRECORD_LHEADER_IMPLEMENTATION (obj);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1597 if (imp->hash)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1598 return imp->hash (obj, depth);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1599 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1600
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1601 return LISP_HASH (obj);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1602 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1603
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1604 DEFUN ("sxhash", Fsxhash, 1, 1, 0, /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1605 Return a hash value for OBJECT.
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
1606 \(equal obj1 obj2) implies (= (sxhash obj1) (sxhash obj2)).
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1607 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1608 (object))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1609 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1610 return make_int (internal_hash (object, 0));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1611 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1612
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1613 #if 0
826
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 801
diff changeset
1614 DEFUN ("internal-hash-value", Finternal_hash_value, 1, 1, 0, /*
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1615 Hash value of OBJECT. For debugging.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1616 The value is returned as (HIGH . LOW).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1617 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1618 (object))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1619 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1620 /* This function is pretty 32bit-centric. */
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1621 Hashcode hash = internal_hash (object, 0);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1622 return Fcons (hash >> 16, hash & 0xffff);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1623 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1624 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1625
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1626
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1627 /************************************************************************/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1628 /* initialization */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1629 /************************************************************************/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1630
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1631 void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1632 syms_of_elhash (void)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1633 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1634 DEFSUBR (Fhash_table_p);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1635 DEFSUBR (Fmake_hash_table);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1636 DEFSUBR (Fcopy_hash_table);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1637 DEFSUBR (Fgethash);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1638 DEFSUBR (Fremhash);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1639 DEFSUBR (Fputhash);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1640 DEFSUBR (Fclrhash);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1641 DEFSUBR (Fmaphash);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1642 DEFSUBR (Fhash_table_count);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1643 DEFSUBR (Fhash_table_test);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1644 DEFSUBR (Fhash_table_size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1645 DEFSUBR (Fhash_table_rehash_size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1646 DEFSUBR (Fhash_table_rehash_threshold);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1647 DEFSUBR (Fhash_table_weakness);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1648 DEFSUBR (Fhash_table_type); /* obsolete */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1649 DEFSUBR (Fsxhash);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1650 #if 0
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1651 DEFSUBR (Finternal_hash_value);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1652 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1653
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1654 DEFSYMBOL_MULTIWORD_PREDICATE (Qhash_tablep);
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1655 DEFSYMBOL (Qhash_table);
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1656 DEFSYMBOL (Qhashtable);
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1657 DEFSYMBOL (Qweakness);
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1658 DEFSYMBOL (Qvalue);
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1659 DEFSYMBOL (Qkey_or_value);
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1660 DEFSYMBOL (Qkey_and_value);
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1661 DEFSYMBOL (Qrehash_size);
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1662 DEFSYMBOL (Qrehash_threshold);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1663
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1664 DEFSYMBOL (Qweak); /* obsolete */
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1665 DEFSYMBOL (Qkey_weak); /* obsolete */
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1666 DEFSYMBOL (Qkey_or_value_weak); /* obsolete */
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1667 DEFSYMBOL (Qvalue_weak); /* obsolete */
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1668 DEFSYMBOL (Qnon_weak); /* obsolete */
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1669
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1670 DEFKEYWORD (Q_test);
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1671 DEFKEYWORD (Q_size);
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1672 DEFKEYWORD (Q_rehash_size);
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1673 DEFKEYWORD (Q_rehash_threshold);
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1674 DEFKEYWORD (Q_weakness);
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1675 DEFKEYWORD (Q_type); /* obsolete */
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1676 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1677
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1678 void
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
1679 init_elhash_once_early (void)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1680 {
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
1681 INIT_LRECORD_IMPLEMENTATION (hash_table);
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
1682
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1683 /* This must NOT be staticpro'd */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1684 Vall_weak_hash_tables = Qnil;
452
3d3049ae1304 Import from CVS: tag r21-2-41
cvs
parents: 450
diff changeset
1685 dump_add_weak_object_chain (&Vall_weak_hash_tables);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1686 }