annotate src/elhash.c @ 793:e38acbeb1cae

[xemacs-hg @ 2002-03-29 04:46:17 by ben] lots o' fixes etc/ChangeLog: New file. Separated out all entries for etc/ into their own ChangeLog. Includes entries for the following files: etc/BABYL, etc/BETA, etc/CHARSETS, etc/DISTRIB, etc/Emacs.ad, etc/FTP, etc/GNUS-NEWS, etc/GOATS, etc/HELLO, etc/INSTALL, etc/MACHINES, etc/MAILINGLISTS, etc/MSDOS, etc/MYTHOLOGY, etc/NEWS, etc/OXYMORONS, etc/PACKAGES, etc/README, etc/TUTORIAL, etc/TUTORIAL.de, etc/TUTORIAL.ja, etc/TUTORIAL.ko, etc/TUTORIAL.se, etc/aliases.ksh, etc/altrasoft-logo.xpm, etc/check_cygwin_setup.sh, etc/custom/example-themes/europe-theme.el, etc/custom/example-themes/ex-custom-file, etc/custom/example-themes/example-theme.el, etc/e/eterm.ti, etc/edt-user.doc, etc/enriched.doc, etc/etags.1, etc/gnuserv.1, etc/gnuserv.README, etc/package-index.LATEST.gpg, etc/package-index.LATEST.pgp, etc/photos/jan.png, etc/recycle.xpm, etc/refcard.tex, etc/sample.Xdefaults, etc/sample.emacs, etc/sgml/CATALOG, etc/sgml/HTML32.dtd, etc/skk/SKK.tut.E, etc/smilies/Face_ase.xbm, etc/smilies/Face_ase2.xbm, etc/smilies/Face_ase3.xbm, etc/smilies/Face_smile.xbm, etc/smilies/Face_weep.xbm, etc/sounds, etc/toolbar, etc/toolbar/workshop-cap-up.xpm, etc/xemacs-ja.1, etc/xemacs.1, etc/yow.lines, etc\BETA, etc\NEWS, etc\README, etc\TUTORIAL, etc\TUTORIAL.de, etc\check_cygwin_setup.sh, etc\sample.init.el, etc\unicode\README, etc\unicode\mule-ucs\*, etc\unicode\other\* unicode/unicode-consortium/8859-16.TXT: New file. mule/english.el: Define this charset now, since a bug was fixed that formerly prevented it. mule/ethio-util.el: Fix compile errors involving Unicode `characters', which should be integers. Makefile.in.in: Always include gui.c, to fix compile error when TTY-only. EmacsFrame.c, abbrev.c, alloc.c, buffer.c, buffer.h, bytecode.c, bytecode.h, callint.c, callproc.c, casetab.c, casetab.h, charset.h, chartab.c, chartab.h, cmds.c, console-msw.c, console-msw.h, console-tty.c, console-x.c, console-x.h, console.c, console.h, data.c, database.c, device-gtk.c, device-msw.c, device-x.c, device.c, device.h, dialog-msw.c, doc.c, doprnt.c, dumper.c, dynarr.c, editfns.c, eldap.c, eldap.h, elhash.c, elhash.h, emacs.c, eval.c, event-Xt.c, event-gtk.c, event-msw.c, event-stream.c, event-tty.c, event-unixoid.c, events.c, events.h, extents.c, extents.h, faces.c, faces.h, file-coding.c, file-coding.h, fileio.c, filelock.c, fns.c, frame-gtk.c, frame-msw.c, frame-tty.c, frame-x.c, frame.c, frame.h, free-hook.c, general-slots.h, glyphs-eimage.c, glyphs-gtk.c, glyphs-msw.c, glyphs-widget.c, glyphs-x.c, glyphs.c, glyphs.h, gpmevent.c, gtk-xemacs.c, gui-msw.c, gui-x.c, gui-x.h, gui.c, gui.h, gutter.c, gutter.h, indent.c, input-method-xlib.c, insdel.c, keymap.c, keymap.h, 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-canna.c, mule-ccl.c, mule-charset.c, mule-wnnfns.c, native-gtk-toolbar.c, objects-msw.c, objects-tty.c, objects-x.c, objects.c, objects.h, opaque.c, opaque.h, postgresql.c, postgresql.h, print.c, process-unix.c, process.c, process.h, rangetab.c, rangetab.h, redisplay-gtk.c, redisplay-msw.c, redisplay-output.c, redisplay-tty.c, redisplay-x.c, redisplay.c, scrollbar-gtk.c, scrollbar-msw.c, scrollbar-x.c, scrollbar.c, scrollbar.h, search.c, select-gtk.c, select-x.c, sound.c, specifier.c, specifier.h, strftime.c, symbols.c, symeval.h, syntax.h, text.c, text.h, toolbar-common.c, toolbar-msw.c, toolbar.c, toolbar.h, tooltalk.c, tooltalk.h, ui-gtk.c, ui-gtk.h, undo.c, vm-limit.c, window.c, window.h: Eliminate XSETFOO. Replace all usages with wrap_foo(). Make symbol->name a Lisp_Object, not Lisp_String *. Eliminate nearly all uses of Lisp_String * in favor of Lisp_Object, and correct macros so most of them favor Lisp_Object. Create new error-behavior ERROR_ME_DEBUG_WARN -- output warnings, but at level `debug' (usually ignored). Use it when instantiating specifiers, so problems can be debugged. Move log-warning-minimum-level into C so that we can optimize ERROR_ME_DEBUG_WARN. Fix warning levels consistent with new definitions. Add default_ and parent fields to char table; not yet implemented. New fun Dynarr_verify(); use for further error checking on Dynarrs. Rearrange code at top of lisp.h in conjunction with dynarr changes. Fix eifree(). Use Eistrings in various places (format_event_object(), where_is_to_char(), and callers thereof) to avoid fixed-size strings buffers. New fun write_eistring(). Reindent and fix GPM code to follow standards. Set default MS Windows font to Lucida Console (same size as Courier New but less interline spacing, so more lines fit). Increase default frame size on Windows to 50 lines. (If that's too big for the workspace, the frame will be shrunk as necessary.) Fix problem with text files with no newlines (). (Change `convert-eol' coding system to use `nil' for autodetect, consistent with make-coding-system.) Correct compile warnings in vm-limit.c. Fix handling of reverse-direction charsets to avoid errors when opening (e.g.) mule-ucs/lisp/reldata/uiso8859-6.el. Recode some object printing methods to use write_fmt_string() instead of a fixed buffer and sprintf. Turn on display of png comments as warnings (level `info'), now that they're unobtrusive. Revamped the sound documentation. Fixed bug in redisplay w.r.t. hscroll/truncation/continuation glyphs causing jumping up and down of the lines, since they're bigger than the line size. (It was seen most obviously when there's a horizontal scroll bar, e.g. do C-h a glyph or something like that.) The problem was that the glyph-contrib-p setting on glyphs was ignored even if it was set properly, which it wasn't until now.
author ben
date Fri, 29 Mar 2002 04:49:13 +0000
parents 943eaba38521
children a5954632b187
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.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3 Copyright (C) 1995, 1996 Ben Wing.
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
123 #ifndef ERROR_CHECK_HASH_TABLE
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
124 # ifdef ERROR_CHECK_TYPECHECK
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
125 # define ERROR_CHECK_HASH_TABLE 1
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
126 # else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
127 # define ERROR_CHECK_HASH_TABLE 0
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
128 # endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
129 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
130
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
131 #if ERROR_CHECK_HASH_TABLE
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
132 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
133 check_hash_table_invariants (Lisp_Hash_Table *ht)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
134 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
135 assert (ht->count < ht->size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
136 assert (ht->count <= ht->rehash_count);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
137 assert (ht->rehash_count < ht->size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
138 assert ((double) ht->count * ht->rehash_threshold - 1 <= (double) ht->rehash_count);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
139 assert (HENTRY_CLEAR_P (ht->hentries + ht->size));
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 #else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
142 #define check_hash_table_invariants(ht)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
143 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
144
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
145 /* 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
146 static Elemcount
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
147 hash_table_size (Elemcount requested_size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
148 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
149 /* Return some prime near, but greater than or equal to, SIZE.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
150 Decades from the time of writing, someone will have a system large
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
151 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
152 static const Elemcount primes [] =
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
153 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
154 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
155 1361, 1777, 2333, 3037, 3967, 5167, 6719, 8737, 11369, 14783,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
156 19219, 24989, 32491, 42257, 54941, 71429, 92861, 120721, 156941,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
157 204047, 265271, 344857, 448321, 582821, 757693, 985003, 1280519,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
158 1664681, 2164111, 2813353, 3657361, 4754591, 6180989, 8035301,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
159 10445899, 13579681, 17653589, 22949669, 29834603, 38784989,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
160 50420551, 65546729, 85210757, 110774011, 144006217, 187208107,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
161 243370577, 316381771, 411296309, 534685237, 695090819, 903618083,
647
b39c14581166 [xemacs-hg @ 2001-08-13 04:45:47 by ben]
ben
parents: 617
diff changeset
162 1174703521, 1527114613, 1985248999 /* , 2580823717UL, 3355070839UL */
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
163 };
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
164 /* We've heard of binary search. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
165 int low, high;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
166 for (low = 0, high = countof (primes) - 1; high - low > 1;)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
167 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
168 /* Loop Invariant: size < primes [high] */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
169 int mid = (low + high) / 2;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
170 if (primes [mid] < requested_size)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
171 low = mid;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
172 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
173 high = mid;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
174 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
175 return primes [high];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
176 }
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
179 #if 0 /* I don't think these are needed any more.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
180 If using the general lisp_object_equal_*() functions
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
181 causes efficiency problems, these can be resurrected. --ben */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
182 /* equality and hash functions for Lisp strings */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
183 int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
184 lisp_string_equal (Lisp_Object str1, Lisp_Object str2)
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 /* This is wrong anyway. You can't use strcmp() on Lisp strings,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
187 because they can contain zero characters. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
188 return !strcmp ((char *) XSTRING_DATA (str1), (char *) XSTRING_DATA (str2));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
189 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
190
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
191 static Hashcode
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
192 lisp_string_hash (Lisp_Object obj)
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 hash_string (XSTRING_DATA (str), XSTRING_LENGTH (str));
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
197 #endif /* 0 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
198
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
199 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
200 lisp_object_eql_equal (Lisp_Object obj1, Lisp_Object obj2)
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 return EQ (obj1, obj2) || (FLOATP (obj1) && internal_equal (obj1, obj2, 0));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
203 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
204
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
205 static Hashcode
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
206 lisp_object_eql_hash (Lisp_Object obj)
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 return FLOATP (obj) ? internal_hash (obj, 0) : LISP_HASH (obj);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
209 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
210
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
211 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
212 lisp_object_equal_equal (Lisp_Object obj1, Lisp_Object obj2)
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 return internal_equal (obj1, obj2, 0);
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
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
217 static Hashcode
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
218 lisp_object_equal_hash (Lisp_Object obj)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
219 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
220 return internal_hash (obj, 0);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
221 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
222
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
223
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
224 static Lisp_Object
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
225 mark_hash_table (Lisp_Object obj)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
226 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
227 Lisp_Hash_Table *ht = XHASH_TABLE (obj);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
228
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
229 /* 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
230 values (we scan over them after everything else has been marked,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
231 and mark or remove them as necessary). */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
232 if (ht->weakness == HASH_TABLE_NON_WEAK)
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 hentry *e, *sentinel;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
235
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
236 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
237 if (!HENTRY_CLEAR_P (e))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
238 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
239 mark_object (e->key);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
240 mark_object (e->value);
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 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
243 return Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
244 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
245
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
246 /* 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
247 the same weakness and test function, they have the same number of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
248 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
249
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
250 This is similar to Common Lisp `equalp' of hash tables, with the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
251 difference that CL requires the keys to be compared with the test
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
252 function, which we don't do. Doing that would require consing, and
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
253 consing is a bad idea in `equal'. Anyway, our method should provide
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
254 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
255 function, then Fgethash() in hash_table_equal_mapper() will fail. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
256 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
257 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
258 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
259 Lisp_Hash_Table *ht1 = XHASH_TABLE (hash_table1);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
260 Lisp_Hash_Table *ht2 = XHASH_TABLE (hash_table2);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
261 hentry *e, *sentinel;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
262
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
263 if ((ht1->test_function != ht2->test_function) ||
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
264 (ht1->weakness != ht2->weakness) ||
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
265 (ht1->count != ht2->count))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
266 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
267
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
268 depth++;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
269
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
270 for (e = ht1->hentries, sentinel = e + ht1->size; e < sentinel; e++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
271 if (!HENTRY_CLEAR_P (e))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
272 /* 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
273 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
274 Lisp_Object value_in_other = Fgethash (e->key, hash_table2, Qunbound);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
275 if (UNBOUNDP (value_in_other) ||
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
276 !internal_equal (e->value, value_in_other, depth))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
277 return 0; /* Give up */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
278 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
279
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
280 return 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
281 }
442
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 /* 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
284 Examining all entries is too expensive, and examining a random
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
285 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
286 static Hashcode
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
287 hash_table_hash (Lisp_Object hash_table, int depth)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
288 {
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
289 return XHASH_TABLE (hash_table)->count;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
290 }
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
291
428
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 /* Printing hash tables.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
294
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
295 This is non-trivial, because we use a readable structure-style
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
296 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
297 readably printed in the form of:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
298
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
299 #s(hash-table size 2 data (key1 value1 key2 value2))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
300
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
301 The supported hash table structure keywords and their values are:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
302 `test' (eql (or nil), eq or equal)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
303 `size' (a natnum or nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
304 `rehash-size' (a float)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
305 `rehash-threshold' (a float)
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
306 `weakness' (nil, key, value, key-and-value, or key-or-value)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
307 `data' (a list)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
308
430
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
309 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
310
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
311 #<hash-table size 2/13 data (key1 value1 key2 value2) 0x874d>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
312
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
313 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
314 `...'. This printer does not cons. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
315
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
316
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
317 /* Print the data of the hash table. This maps through a Lisp
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
318 hash table and prints key/value pairs using PRINTCHARFUN. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
319 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
320 print_hash_table_data (Lisp_Hash_Table *ht, Lisp_Object printcharfun)
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 int count = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
323 hentry *e, *sentinel;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
324
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
325 write_c_string (" data (", printcharfun);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
326
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
327 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
328 if (!HENTRY_CLEAR_P (e))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
329 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
330 if (count > 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
331 write_c_string (" ", printcharfun);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
332 if (!print_readably && count > 3)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
333 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
334 write_c_string ("...", printcharfun);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
335 break;
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 print_internal (e->key, printcharfun, 1);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
338 write_c_string (" ", printcharfun);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
339 print_internal (e->value, printcharfun, 1);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
340 count++;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
341 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
342
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
343 write_c_string (")", printcharfun);
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
346 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
347 print_hash_table (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
348 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
349 Lisp_Hash_Table *ht = XHASH_TABLE (obj);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
350 char buf[128];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
351
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
352 write_c_string (print_readably ? "#s(hash-table" : "#<hash-table",
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
353 printcharfun);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
354
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
355 /* These checks have a kludgy look to them, but they are safe.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
356 Due to nature of hashing, you cannot use arbitrary
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
357 test functions anyway. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
358 if (!ht->test_function)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
359 write_c_string (" test eq", printcharfun);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
360 else if (ht->test_function == lisp_object_equal_equal)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
361 write_c_string (" test equal", printcharfun);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
362 else if (ht->test_function == lisp_object_eql_equal)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
363 DO_NOTHING;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
364 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
365 abort ();
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
366
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
367 if (ht->count || !print_readably)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
368 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
369 if (print_readably)
647
b39c14581166 [xemacs-hg @ 2001-08-13 04:45:47 by ben]
ben
parents: 617
diff changeset
370 sprintf (buf, " size %ld", (long) ht->count);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
371 else
647
b39c14581166 [xemacs-hg @ 2001-08-13 04:45:47 by ben]
ben
parents: 617
diff changeset
372 sprintf (buf, " size %ld/%ld", (long) ht->count, (long) ht->size);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
373 write_c_string (buf, printcharfun);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
374 }
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 if (ht->weakness != HASH_TABLE_NON_WEAK)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
377 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
378 sprintf (buf, " weakness %s",
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
379 (ht->weakness == HASH_TABLE_WEAK ? "key-and-value" :
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
380 ht->weakness == HASH_TABLE_KEY_WEAK ? "key" :
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
381 ht->weakness == HASH_TABLE_VALUE_WEAK ? "value" :
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
382 ht->weakness == HASH_TABLE_KEY_VALUE_WEAK ? "key-or-value" :
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
383 "you-d-better-not-see-this"));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
384 write_c_string (buf, printcharfun);
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 if (ht->count)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
388 print_hash_table_data (ht, printcharfun);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
389
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
390 if (print_readably)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
391 write_c_string (")", printcharfun);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
392 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
393 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
394 sprintf (buf, " 0x%x>", ht->header.uid);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
395 write_c_string (buf, printcharfun);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
396 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
397 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
398
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
399 static void
489
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
400 free_hentries (hentry *hentries, size_t size)
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 #if ERROR_CHECK_HASH_TABLE
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
403 /* 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
404 hentry *e, *sentinel;
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
405
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
406 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
407 * (unsigned long *) e = 0xdeadbeef;
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
408 #endif
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
409
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
410 if (!DUMPEDP (hentries))
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
411 xfree (hentries);
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
412 }
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
413
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
414 static void
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
415 finalize_hash_table (void *header, int for_disksave)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
416 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
417 if (!for_disksave)
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 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
420 free_hentries (ht->hentries, ht->size);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
421 ht->hentries = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
422 }
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 static const struct lrecord_description hentry_description_1[] = {
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
426 { XD_LISP_OBJECT, offsetof (hentry, key) },
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
427 { XD_LISP_OBJECT, offsetof (hentry, value) },
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
428 { XD_END }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
429 };
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 static const struct struct_description hentry_description = {
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
432 sizeof (hentry),
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
433 hentry_description_1
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
434 };
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
435
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
436 const struct lrecord_description hash_table_description[] = {
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
437 { XD_ELEMCOUNT, offsetof (Lisp_Hash_Table, size) },
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
438 { 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
439 { XD_LO_LINK, offsetof (Lisp_Hash_Table, next_weak) },
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
440 { XD_END }
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
443 DEFINE_LRECORD_IMPLEMENTATION ("hash-table", hash_table,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
444 mark_hash_table, print_hash_table,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
445 finalize_hash_table,
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
446 hash_table_equal, hash_table_hash,
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
447 hash_table_description,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
448 Lisp_Hash_Table);
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 static Lisp_Hash_Table *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
451 xhash_table (Lisp_Object hash_table)
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 if (!gc_in_progress)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
454 CHECK_HASH_TABLE (hash_table);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
455 check_hash_table_invariants (XHASH_TABLE (hash_table));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
456 return XHASH_TABLE (hash_table);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
457 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
458
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
459
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
460 /************************************************************************/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
461 /* Creation of Hash Tables */
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
464 /* Creation of hash tables, without error-checking. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
465 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
466 compute_hash_table_derived_values (Lisp_Hash_Table *ht)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
467 {
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
468 ht->rehash_count = (Elemcount)
438
84b14dcb0985 Import from CVS: tag r21-2-27
cvs
parents: 434
diff changeset
469 ((double) ht->size * ht->rehash_threshold);
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
470 ht->golden_ratio = (Elemcount)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
471 ((double) ht->size * (.6180339887 / (double) sizeof (Lisp_Object)));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
472 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
473
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
474 Lisp_Object
450
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
475 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
476 Elemcount size,
450
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
477 double rehash_size,
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
478 double rehash_threshold,
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
479 enum hash_table_weakness weakness)
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
480 {
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents: 458
diff changeset
481 hash_table_hash_function_t hash_function = 0;
450
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
482 hash_table_test_function_t test_function = 0;
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
483
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
484 switch (test)
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
485 {
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
486 case HASH_TABLE_EQ:
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
487 test_function = 0;
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
488 hash_function = 0;
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
489 break;
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
490
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
491 case HASH_TABLE_EQL:
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
492 test_function = lisp_object_eql_equal;
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
493 hash_function = lisp_object_eql_hash;
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
494 break;
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
495
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
496 case HASH_TABLE_EQUAL:
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
497 test_function = lisp_object_equal_equal;
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
498 hash_function = lisp_object_equal_hash;
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
499 break;
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
500
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
501 default:
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
502 abort ();
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
503 }
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
504
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
505 return make_general_lisp_hash_table (hash_function, test_function,
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
506 size, rehash_size, rehash_threshold,
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
507 weakness);
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
508 }
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
509
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
510 Lisp_Object
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
511 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
512 hash_table_test_function_t test_function,
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
513 Elemcount size,
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
514 double rehash_size,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
515 double rehash_threshold,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
516 enum hash_table_weakness weakness)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
517 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
518 Lisp_Object hash_table;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
519 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
520
450
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
521 ht->test_function = test_function;
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
522 ht->hash_function = hash_function;
438
84b14dcb0985 Import from CVS: tag r21-2-27
cvs
parents: 434
diff changeset
523 ht->weakness = weakness;
84b14dcb0985 Import from CVS: tag r21-2-27
cvs
parents: 434
diff changeset
524
84b14dcb0985 Import from CVS: tag r21-2-27
cvs
parents: 434
diff changeset
525 ht->rehash_size =
84b14dcb0985 Import from CVS: tag r21-2-27
cvs
parents: 434
diff changeset
526 rehash_size > 1.0 ? rehash_size : HASH_TABLE_DEFAULT_REHASH_SIZE;
84b14dcb0985 Import from CVS: tag r21-2-27
cvs
parents: 434
diff changeset
527
84b14dcb0985 Import from CVS: tag r21-2-27
cvs
parents: 434
diff changeset
528 ht->rehash_threshold =
84b14dcb0985 Import from CVS: tag r21-2-27
cvs
parents: 434
diff changeset
529 rehash_threshold > 0.0 ? rehash_threshold :
84b14dcb0985 Import from CVS: tag r21-2-27
cvs
parents: 434
diff changeset
530 size > 4096 && !ht->test_function ? 0.7 : 0.6;
84b14dcb0985 Import from CVS: tag r21-2-27
cvs
parents: 434
diff changeset
531
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
532 if (size < HASH_TABLE_MIN_SIZE)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
533 size = HASH_TABLE_MIN_SIZE;
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
534 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
535 + 1.0));
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
536 ht->count = 0;
438
84b14dcb0985 Import from CVS: tag r21-2-27
cvs
parents: 434
diff changeset
537
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
538 compute_hash_table_derived_values (ht);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
539
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
540 /* 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
541 ht->hentries = xnew_array_and_zero (hentry, ht->size + 1);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
542
793
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 771
diff changeset
543 hash_table = wrap_hash_table (ht);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
544
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
545 if (weakness == HASH_TABLE_NON_WEAK)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
546 ht->next_weak = Qunbound;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
547 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
548 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
549
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
550 return hash_table;
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
553 Lisp_Object
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
554 make_lisp_hash_table (Elemcount size,
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
555 enum hash_table_weakness weakness,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
556 enum hash_table_test test)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
557 {
450
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
558 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
559 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
560
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
561 /* Pretty reading of hash tables.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
562
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
563 Here we use the existing structures mechanism (which is,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
564 unfortunately, pretty cumbersome) for validating and instantiating
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
565 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
566 #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
567 properties, and that the hash table is returned. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
568
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
569 /* Validation functions: each keyword provides its own validation
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
570 function. The errors should maybe be continuable, but it is
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
571 unclear how this would cope with ERRB. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
572 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
573 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
574 Error_Behavior errb)
428
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 if (NATNUMP (value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
577 return 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
578
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
579 maybe_signal_error_1 (Qwrong_type_argument, list2 (Qnatnump, value),
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
580 Qhash_table, errb);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
581 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
582 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
583
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
584 static Elemcount
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
585 decode_hash_table_size (Lisp_Object obj)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
586 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
587 return NILP (obj) ? HASH_TABLE_DEFAULT_SIZE : XINT (obj);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
588 }
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 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
591 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
592 Error_Behavior errb)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
593 {
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
594 if (EQ (value, Qnil)) return 1;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
595 if (EQ (value, Qt)) return 1;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
596 if (EQ (value, Qkey)) return 1;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
597 if (EQ (value, Qkey_and_value)) return 1;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
598 if (EQ (value, Qkey_or_value)) return 1;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
599 if (EQ (value, Qvalue)) return 1;
428
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 /* 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
602 if (EQ (value, Qnon_weak)) return 1;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
603 if (EQ (value, Qweak)) return 1;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
604 if (EQ (value, Qkey_weak)) return 1;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
605 if (EQ (value, Qkey_or_value_weak)) return 1;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
606 if (EQ (value, Qvalue_weak)) return 1;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
607
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
608 maybe_invalid_constant ("Invalid hash table weakness",
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
609 value, Qhash_table, errb);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
610 return 0;
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
613 static enum hash_table_weakness
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
614 decode_hash_table_weakness (Lisp_Object obj)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
615 {
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
616 if (EQ (obj, Qnil)) return HASH_TABLE_NON_WEAK;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
617 if (EQ (obj, Qt)) return HASH_TABLE_WEAK;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
618 if (EQ (obj, Qkey_and_value)) return HASH_TABLE_WEAK;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
619 if (EQ (obj, Qkey)) return HASH_TABLE_KEY_WEAK;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
620 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
621 if (EQ (obj, Qvalue)) return HASH_TABLE_VALUE_WEAK;
428
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 /* 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
624 if (EQ (obj, Qnon_weak)) return HASH_TABLE_NON_WEAK;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
625 if (EQ (obj, Qweak)) return HASH_TABLE_WEAK;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
626 if (EQ (obj, Qkey_weak)) return HASH_TABLE_KEY_WEAK;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
627 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
628 if (EQ (obj, Qvalue_weak)) return HASH_TABLE_VALUE_WEAK;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
629
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
630 invalid_constant ("Invalid hash table weakness", obj);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
631 return HASH_TABLE_NON_WEAK; /* not reached */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
632 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
633
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
634 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
635 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
636 Error_Behavior errb)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
637 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
638 if (EQ (value, Qnil)) return 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
639 if (EQ (value, Qeq)) return 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
640 if (EQ (value, Qequal)) return 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
641 if (EQ (value, Qeql)) return 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
642
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
643 maybe_invalid_constant ("Invalid hash table test",
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
644 value, Qhash_table, errb);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
645 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
646 }
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 static enum hash_table_test
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
649 decode_hash_table_test (Lisp_Object obj)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
650 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
651 if (EQ (obj, Qnil)) return HASH_TABLE_EQL;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
652 if (EQ (obj, Qeq)) return HASH_TABLE_EQ;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
653 if (EQ (obj, Qequal)) return HASH_TABLE_EQUAL;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
654 if (EQ (obj, Qeql)) return HASH_TABLE_EQL;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
655
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
656 invalid_constant ("Invalid hash table test", obj);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
657 return HASH_TABLE_EQ; /* not reached */
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 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
661 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
662 Error_Behavior errb)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
663 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
664 if (!FLOATP (value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
665 {
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
666 maybe_signal_error_1 (Qwrong_type_argument, list2 (Qfloatp, value),
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
667 Qhash_table, errb);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
668 return 0;
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 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
672 double rehash_size = XFLOAT_DATA (value);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
673 if (rehash_size <= 1.0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
674 {
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
675 maybe_invalid_argument
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
676 ("Hash table rehash size must be greater than 1.0",
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
677 value, Qhash_table, errb);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
678 return 0;
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 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
681
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
682 return 1;
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
685 static double
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
686 decode_hash_table_rehash_size (Lisp_Object rehash_size)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
687 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
688 return NILP (rehash_size) ? -1.0 : XFLOAT_DATA (rehash_size);
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 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
692 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
693 Error_Behavior errb)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
694 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
695 if (!FLOATP (value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
696 {
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
697 maybe_signal_error_1 (Qwrong_type_argument, list2 (Qfloatp, value),
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
698 Qhash_table, errb);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
699 return 0;
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 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
703 double rehash_threshold = XFLOAT_DATA (value);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
704 if (rehash_threshold <= 0.0 || rehash_threshold >= 1.0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
705 {
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
706 maybe_invalid_argument
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
707 ("Hash table rehash threshold must be between 0.0 and 1.0",
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
708 value, Qhash_table, errb);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
709 return 0;
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 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
712
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
713 return 1;
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
716 static double
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
717 decode_hash_table_rehash_threshold (Lisp_Object rehash_threshold)
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 return NILP (rehash_threshold) ? -1.0 : XFLOAT_DATA (rehash_threshold);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
720 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
721
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
722 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
723 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
724 Error_Behavior errb)
428
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 int len;
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 GET_EXTERNAL_LIST_LENGTH (value, len);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
729
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
730 if (len & 1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
731 {
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
732 maybe_sferror
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
733 ("Hash table data must have alternating key/value pairs",
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
734 value, Qhash_table, errb);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
735 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
736 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
737 return 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
738 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
739
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
740 /* The actual instantiation of a hash table. This does practically no
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
741 error checking, because it relies on the fact that the paranoid
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
742 functions above have error-checked everything to the last details.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
743 If this assumption is wrong, we will get a crash immediately (with
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
744 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
745 the structure mechanism. So there. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
746 static Lisp_Object
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
747 hash_table_instantiate (Lisp_Object plist)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
748 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
749 Lisp_Object hash_table;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
750 Lisp_Object test = Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
751 Lisp_Object size = Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
752 Lisp_Object rehash_size = Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
753 Lisp_Object rehash_threshold = Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
754 Lisp_Object weakness = Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
755 Lisp_Object data = Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
756
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
757 while (!NILP (plist))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
758 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
759 Lisp_Object key, value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
760 key = XCAR (plist); plist = XCDR (plist);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
761 value = XCAR (plist); plist = XCDR (plist);
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 if (EQ (key, Qtest)) test = value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
764 else if (EQ (key, Qsize)) size = value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
765 else if (EQ (key, Qrehash_size)) rehash_size = value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
766 else if (EQ (key, Qrehash_threshold)) rehash_threshold = value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
767 else if (EQ (key, Qweakness)) weakness = value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
768 else if (EQ (key, Qdata)) data = value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
769 else if (EQ (key, Qtype))/*obsolete*/ weakness = value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
770 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
771 abort ();
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
774 /* Create the hash table. */
450
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
775 hash_table = make_standard_lisp_hash_table
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
776 (decode_hash_table_test (test),
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
777 decode_hash_table_size (size),
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
778 decode_hash_table_rehash_size (rehash_size),
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
779 decode_hash_table_rehash_threshold (rehash_threshold),
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
780 decode_hash_table_weakness (weakness));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
781
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
782 /* 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
783 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
784 struct gcpro gcpro1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
785 GCPRO1 (hash_table);
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 /* And fill it with data. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
788 while (!NILP (data))
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 Lisp_Object key, value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
791 key = XCAR (data); data = XCDR (data);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
792 value = XCAR (data); data = XCDR (data);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
793 Fputhash (key, value, hash_table);
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 UNGCPRO;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
796 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
797
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
798 return hash_table;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
799 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
800
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
801 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
802 structure_type_create_hash_table_structure_name (Lisp_Object structure_name)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
803 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
804 struct structure_type *st;
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 st = define_structure_type (structure_name, 0, hash_table_instantiate);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
807 define_structure_type_keyword (st, Qtest, hash_table_test_validate);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
808 define_structure_type_keyword (st, Qsize, hash_table_size_validate);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
809 define_structure_type_keyword (st, Qrehash_size, hash_table_rehash_size_validate);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
810 define_structure_type_keyword (st, Qrehash_threshold, hash_table_rehash_threshold_validate);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
811 define_structure_type_keyword (st, Qweakness, hash_table_weakness_validate);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
812 define_structure_type_keyword (st, Qdata, hash_table_data_validate);
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 /* obsolete as of 19990901 in xemacs-21.2 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
815 define_structure_type_keyword (st, Qtype, hash_table_weakness_validate);
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 /* Create a built-in Lisp structure type named `hash-table'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
819 We make #s(hashtable ...) equivalent to #s(hash-table ...),
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
820 for backward compatibility.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
821 This is called from emacs.c. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
822 void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
823 structure_type_create_hash_table (void)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
824 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
825 structure_type_create_hash_table_structure_name (Qhash_table);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
826 structure_type_create_hash_table_structure_name (Qhashtable); /* compat */
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
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 /* Definition of Lisp-visible methods */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
832 /************************************************************************/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
833
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
834 DEFUN ("hash-table-p", Fhash_table_p, 1, 1, 0, /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
835 Return t if OBJECT is a hash table, else nil.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
836 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
837 (object))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
838 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
839 return HASH_TABLEP (object) ? Qt : Qnil;
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
842 DEFUN ("make-hash-table", Fmake_hash_table, 0, MANY, 0, /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
843 Return a new empty hash table object.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
844 Use Common Lisp style keywords to specify hash table properties.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
845 (make-hash-table &key test size rehash-size rehash-threshold weakness)
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 :test can be `eq', `eql' (default) or `equal'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
848 Comparison between keys is done using this function.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
849 If speed is important, consider using `eq'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
850 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
851
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
852 Keyword :size specifies the number of keys likely to be inserted.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
853 This number of entries can be inserted without enlarging the hash table.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
854
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
855 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
856 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
857
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
858 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
859 and specifies the load factor of the hash table which triggers enlarging.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
860
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
861 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
862 `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
863
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
864 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
865 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
866 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
867 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
868 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
869 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
870 would prevent the object from being collected.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
871
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
872 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
873 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
874 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
875 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
876 if the value is not.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
877
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
878 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
879 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
880 unmarked outside of weak hash tables. The pair will remain in the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
881 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
882 hash table, even if the key is not.
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
883
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
884 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
885 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
886 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
887 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
888 hash table, even if the other is not.
428
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 (int nargs, Lisp_Object *args))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
891 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
892 int i = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
893 Lisp_Object test = Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
894 Lisp_Object size = Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
895 Lisp_Object rehash_size = Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
896 Lisp_Object rehash_threshold = Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
897 Lisp_Object weakness = Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
898
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
899 while (i + 1 < nargs)
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 Lisp_Object keyword = args[i++];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
902 Lisp_Object value = args[i++];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
903
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
904 if (EQ (keyword, Q_test)) test = value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
905 else if (EQ (keyword, Q_size)) size = value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
906 else if (EQ (keyword, Q_rehash_size)) rehash_size = value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
907 else if (EQ (keyword, Q_rehash_threshold)) rehash_threshold = value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
908 else if (EQ (keyword, Q_weakness)) weakness = value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
909 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
910 else invalid_constant ("Invalid hash table property keyword", keyword);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
911 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
912
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
913 if (i < nargs)
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
914 sferror ("Hash table property requires a value", args[i]);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
915
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
916 #define VALIDATE_VAR(var) \
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
917 if (!NILP (var)) hash_table_##var##_validate (Q##var, var, ERROR_ME);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
918
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
919 VALIDATE_VAR (test);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
920 VALIDATE_VAR (size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
921 VALIDATE_VAR (rehash_size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
922 VALIDATE_VAR (rehash_threshold);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
923 VALIDATE_VAR (weakness);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
924
450
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
925 return make_standard_lisp_hash_table
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
926 (decode_hash_table_test (test),
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
927 decode_hash_table_size (size),
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
928 decode_hash_table_rehash_size (rehash_size),
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
929 decode_hash_table_rehash_threshold (rehash_threshold),
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
930 decode_hash_table_weakness (weakness));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
931 }
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 DEFUN ("copy-hash-table", Fcopy_hash_table, 1, 1, 0, /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
934 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
935 The keys and values will not themselves be copied.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
936 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
937 (hash_table))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
938 {
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
939 const Lisp_Hash_Table *ht_old = xhash_table (hash_table);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
940 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
941
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
942 copy_lcrecord (ht, ht_old);
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 ht->hentries = xnew_array (hentry, ht_old->size + 1);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
945 memcpy (ht->hentries, ht_old->hentries, (ht_old->size + 1) * sizeof (hentry));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
946
793
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 771
diff changeset
947 hash_table = wrap_hash_table (ht);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
948
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
949 if (! EQ (ht->next_weak, Qunbound))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
950 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
951 ht->next_weak = Vall_weak_hash_tables;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
952 Vall_weak_hash_tables = hash_table;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
953 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
954
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
955 return hash_table;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
956 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
957
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
958 static void
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
959 resize_hash_table (Lisp_Hash_Table *ht, Elemcount new_size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
960 {
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
961 hentry *old_entries, *new_entries, *sentinel, *e;
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
962 Elemcount old_size;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
963
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
964 old_size = ht->size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
965 ht->size = new_size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
966
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
967 old_entries = ht->hentries;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
968
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
969 ht->hentries = xnew_array_and_zero (hentry, new_size + 1);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
970 new_entries = ht->hentries;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
971
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
972 compute_hash_table_derived_values (ht);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
973
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
974 for (e = old_entries, sentinel = e + old_size; e < sentinel; e++)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
975 if (!HENTRY_CLEAR_P (e))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
976 {
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
977 hentry *probe = new_entries + HASHCODE (e->key, ht);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
978 LINEAR_PROBING_LOOP (probe, new_entries, new_size)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
979 ;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
980 *probe = *e;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
981 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
982
489
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
983 free_hentries (old_entries, old_size);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
984 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
985
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
986 /* 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
987 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
988 and thus their HASHCODEs have changed. */
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
989 void
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
990 pdump_reorganize_hash_table (Lisp_Object hash_table)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
991 {
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
992 const Lisp_Hash_Table *ht = xhash_table (hash_table);
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
993 hentry *new_entries = xnew_array_and_zero (hentry, ht->size + 1);
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
994 hentry *e, *sentinel;
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 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
997 if (!HENTRY_CLEAR_P (e))
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
998 {
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
999 hentry *probe = new_entries + HASHCODE (e->key, ht);
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
1000 LINEAR_PROBING_LOOP (probe, new_entries, ht->size)
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
1001 ;
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
1002 *probe = *e;
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
1003 }
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
1004
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
1005 memcpy (ht->hentries, new_entries, ht->size * sizeof (hentry));
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
1006
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 438
diff changeset
1007 xfree (new_entries);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1008 }
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 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1011 enlarge_hash_table (Lisp_Hash_Table *ht)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1012 {
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1013 Elemcount new_size =
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1014 hash_table_size ((Elemcount) ((double) ht->size * ht->rehash_size));
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1015 resize_hash_table (ht, new_size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1016 }
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 static hentry *
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1019 find_hentry (Lisp_Object key, const Lisp_Hash_Table *ht)
428
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 hash_table_test_function_t test_function = ht->test_function;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1022 hentry *entries = ht->hentries;
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1023 hentry *probe = entries + HASHCODE (key, ht);
428
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 LINEAR_PROBING_LOOP (probe, entries, ht->size)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1026 if (KEYS_EQUAL_P (probe->key, key, test_function))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1027 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1028
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1029 return probe;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1030 }
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 DEFUN ("gethash", Fgethash, 2, 3, 0, /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1033 Find hash value for KEY in HASH-TABLE.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1034 If there is no corresponding value, return DEFAULT (which defaults to nil).
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, hash_table, default_))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1037 {
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1038 const Lisp_Hash_Table *ht = xhash_table (hash_table);
428
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 return HENTRY_CLEAR_P (e) ? default_ : e->value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1042 }
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 DEFUN ("puthash", Fputhash, 3, 3, 0, /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1045 Hash KEY to VALUE in HASH-TABLE.
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 (key, value, hash_table))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1048 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1049 Lisp_Hash_Table *ht = xhash_table (hash_table);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1050 hentry *e = find_hentry (key, ht);
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 if (!HENTRY_CLEAR_P (e))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1053 return e->value = value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1054
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1055 e->key = key;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1056 e->value = value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1057
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1058 if (++ht->count >= ht->rehash_count)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1059 enlarge_hash_table (ht);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1060
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1061 return value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1062 }
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 /* Remove hentry pointed at by PROBE.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1065 Subsequent entries are removed and reinserted.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1066 We don't use tombstones - too wasteful. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1067 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1068 remhash_1 (Lisp_Hash_Table *ht, hentry *entries, hentry *probe)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1069 {
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1070 Elemcount size = ht->size;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1071 CLEAR_HENTRY (probe);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1072 probe++;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1073 ht->count--;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1074
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1075 LINEAR_PROBING_LOOP (probe, entries, size)
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 Lisp_Object key = probe->key;
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1078 hentry *probe2 = entries + HASHCODE (key, ht);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1079 LINEAR_PROBING_LOOP (probe2, entries, size)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1080 if (EQ (probe2->key, key))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1081 /* hentry at probe doesn't need to move. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1082 goto continue_outer_loop;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1083 /* Move hentry from probe to new home at probe2. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1084 *probe2 = *probe;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1085 CLEAR_HENTRY (probe);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1086 continue_outer_loop: continue;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1087 }
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1090 DEFUN ("remhash", Fremhash, 2, 2, 0, /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1091 Remove the entry for KEY from HASH-TABLE.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1092 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
1093 Return non-nil if an entry was removed.
428
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 (key, hash_table))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1096 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1097 Lisp_Hash_Table *ht = xhash_table (hash_table);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1098 hentry *e = find_hentry (key, ht);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1099
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1100 if (HENTRY_CLEAR_P (e))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1101 return Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1102
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1103 remhash_1 (ht, ht->hentries, e);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1104 return Qt;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1105 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1106
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1107 DEFUN ("clrhash", Fclrhash, 1, 1, 0, /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1108 Remove all entries from HASH-TABLE, leaving it empty.
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 (hash_table))
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 Lisp_Hash_Table *ht = xhash_table (hash_table);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1113 hentry *e, *sentinel;
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 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1116 CLEAR_HENTRY (e);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1117 ht->count = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1118
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1119 return hash_table;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1120 }
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 /* Accessor Functions */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1124 /************************************************************************/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1125
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1126 DEFUN ("hash-table-count", Fhash_table_count, 1, 1, 0, /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1127 Return the number of entries in 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))
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 make_int (xhash_table (hash_table)->count);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1132 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1133
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1134 DEFUN ("hash-table-test", Fhash_table_test, 1, 1, 0, /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1135 Return the test function of HASH-TABLE.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1136 This can be one of `eq', `eql' or `equal'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1137 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1138 (hash_table))
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_test_function_t fun = xhash_table (hash_table)->test_function;
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 (fun == lisp_object_eql_equal ? Qeql :
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1143 fun == lisp_object_equal_equal ? Qequal :
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1144 Qeq);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1145 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1146
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1147 DEFUN ("hash-table-size", Fhash_table_size, 1, 1, 0, /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1148 Return the size of HASH-TABLE.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1149 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
1150 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1151 (hash_table))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1152 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1153 return make_int (xhash_table (hash_table)->size);
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1156 DEFUN ("hash-table-rehash-size", Fhash_table_rehash_size, 1, 1, 0, /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1157 Return the current rehash size of HASH-TABLE.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1158 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
1159 is enlarged when the rehash threshold is exceeded.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1160 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1161 (hash_table))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1162 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1163 return make_float (xhash_table (hash_table)->rehash_size);
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1166 DEFUN ("hash-table-rehash-threshold", Fhash_table_rehash_threshold, 1, 1, 0, /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1167 Return the current rehash threshold of HASH-TABLE.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1168 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
1169 beyond which the HASH-TABLE is enlarged by rehashing.
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 (hash_table))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1172 {
438
84b14dcb0985 Import from CVS: tag r21-2-27
cvs
parents: 434
diff changeset
1173 return make_float (xhash_table (hash_table)->rehash_threshold);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1174 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1175
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1176 DEFUN ("hash-table-weakness", Fhash_table_weakness, 1, 1, 0, /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1177 Return the weakness of HASH-TABLE.
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1178 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
1179 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1180 (hash_table))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1181 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1182 switch (xhash_table (hash_table)->weakness)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1183 {
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1184 case HASH_TABLE_WEAK: return Qkey_and_value;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1185 case HASH_TABLE_KEY_WEAK: return Qkey;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1186 case HASH_TABLE_KEY_VALUE_WEAK: return Qkey_or_value;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1187 case HASH_TABLE_VALUE_WEAK: return Qvalue;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1188 default: return Qnil;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1189 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1190 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1191
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1192 /* obsolete as of 19990901 in xemacs-21.2 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1193 DEFUN ("hash-table-type", Fhash_table_type, 1, 1, 0, /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1194 Return the type of HASH-TABLE.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1195 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
1196 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1197 (hash_table))
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 switch (xhash_table (hash_table)->weakness)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1200 {
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1201 case HASH_TABLE_WEAK: return Qweak;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1202 case HASH_TABLE_KEY_WEAK: return Qkey_weak;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1203 case HASH_TABLE_KEY_VALUE_WEAK: return Qkey_or_value_weak;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1204 case HASH_TABLE_VALUE_WEAK: return Qvalue_weak;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1205 default: return Qnon_weak;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1206 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1207 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1208
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1209 /************************************************************************/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1210 /* Mapping Functions */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1211 /************************************************************************/
489
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1212
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1213 /* 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
1214 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
1215 - by the mapping function
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1216 - by gc (if the hash table is weak)
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1217
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1218 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
1219 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
1220 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
1221 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
1222 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
1223
11b53bb7daf5 [xemacs-hg @ 2001-05-02 10:22:58 by martinb]
martinb
parents: 489
diff changeset
1224 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
1225 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
1226 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
1227 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
1228 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
1229 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
1230 functions gethash, puthash and remhash should be implementable
11b53bb7daf5 [xemacs-hg @ 2001-05-02 10:22:58 by martinb]
martinb
parents: 489
diff changeset
1231 without having to think about maphash.
11b53bb7daf5 [xemacs-hg @ 2001-05-02 10:22:58 by martinb]
martinb
parents: 489
diff changeset
1232
11b53bb7daf5 [xemacs-hg @ 2001-05-02 10:22:58 by martinb]
martinb
parents: 489
diff changeset
1233 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
1234 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
1235 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
1236 function in perl has this limitation.
11b53bb7daf5 [xemacs-hg @ 2001-05-02 10:22:58 by martinb]
martinb
parents: 489
diff changeset
1237
11b53bb7daf5 [xemacs-hg @ 2001-05-02 10:22:58 by martinb]
martinb
parents: 489
diff changeset
1238 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
1239 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
1240 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
1241
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
1242 -- Martin
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
1243 */
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
1244
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
1245 /* 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
1246
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
1247 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
1248 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
1249 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
1250 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
1251 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
1252 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
1253 single extra check for this secondary table -- totally
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
1254 insignificant speedwise. if you really cared about making
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
1255 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
1256 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
1257 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
1258 table when mapping. the advantages of this are
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
1259
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
1260 [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
1261
bcda0b3445a6 [xemacs-hg @ 2001-05-05 08:19:18 by martinb]
martinb
parents: 497
diff changeset
1262 [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
1263 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
1264 very small.
497
11b53bb7daf5 [xemacs-hg @ 2001-05-02 10:22:58 by martinb]
martinb
parents: 489
diff changeset
1265 */
11b53bb7daf5 [xemacs-hg @ 2001-05-02 10:22:58 by martinb]
martinb
parents: 489
diff changeset
1266
489
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1267 static Lisp_Object
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1268 maphash_unwind (Lisp_Object unwind_obj)
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1269 {
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1270 void *ptr = (void *) get_opaque_ptr (unwind_obj);
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1271 xfree (ptr);
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1272 free_opaque_ptr (unwind_obj);
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1273 return Qnil;
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
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1276 /* 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
1277 static Lisp_Object *
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1278 copy_compress_hentries (const Lisp_Hash_Table *ht)
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1279 {
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1280 Lisp_Object * const objs =
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1281 /* 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
1282 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
1283 const hentry *e, *sentinel;
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1284 Lisp_Object *pobj;
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 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
1287 if (!HENTRY_CLEAR_P (e))
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1288 {
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1289 *(pobj++) = e->key;
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1290 *(pobj++) = e->value;
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1291 }
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1292
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1293 type_checking_assert (pobj == objs + 2 * ht->count);
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1294
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1295 return objs;
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1296 }
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1297
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1298 DEFUN ("maphash", Fmaphash, 2, 2, 0, /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1299 Map FUNCTION over entries in HASH-TABLE, calling it with two args,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1300 each key and value in HASH-TABLE.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1301
489
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1302 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
1303 may remhash or puthash the entry currently being processed by FUNCTION.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1304 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1305 (function, hash_table))
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 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
1308 Lisp_Object * const objs = copy_compress_hentries (ht);
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1309 Lisp_Object args[3];
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1310 const Lisp_Object *pobj, *end;
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1311 int speccount = specpdl_depth ();
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1312 struct gcpro gcpro1;
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1313
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1314 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
1315 GCPRO1 (objs[0]);
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1316 gcpro1.nvars = 2 * ht->count;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1317
489
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1318 args[0] = function;
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1319
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1320 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
1321 {
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1322 args[1] = pobj[0];
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1323 args[2] = pobj[1];
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1324 Ffuncall (countof (args), args);
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1325 }
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1326
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
1327 unbind_to (speccount);
489
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1328 UNGCPRO;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1329
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1330 return Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1331 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1332
489
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1333 /* 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
1334 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
1335 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
1336 Mapping terminates if FUNCTION returns something other than 0. */
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1337 void
489
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1338 elisp_maphash_unsafe (maphash_function_t function,
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1339 Lisp_Object hash_table, void *extra_arg)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1340 {
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1341 const Lisp_Hash_Table *ht = XHASH_TABLE (hash_table);
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1342 const hentry *e, *sentinel;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1343
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1344 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1345 if (!HENTRY_CLEAR_P (e))
489
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1346 if (function (e->key, e->value, extra_arg))
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1347 return;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1348 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1349
489
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1350 /* 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
1351 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
1352 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
1353 void
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1354 elisp_maphash (maphash_function_t function,
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1355 Lisp_Object hash_table, void *extra_arg)
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1356 {
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1357 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
1358 Lisp_Object * const objs = copy_compress_hentries (ht);
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1359 const Lisp_Object *pobj, *end;
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1360 int speccount = specpdl_depth ();
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1361 struct gcpro gcpro1;
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 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
1364 GCPRO1 (objs[0]);
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1365 gcpro1.nvars = 2 * ht->count;
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1366
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1367 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
1368 if (function (pobj[0], pobj[1], extra_arg))
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1369 break;
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1370
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
1371 unbind_to (speccount);
489
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1372 UNGCPRO;
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1373 }
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1374
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1375 /* 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
1376 PREDICATE must not modify HASH-TABLE. */
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1377 void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1378 elisp_map_remhash (maphash_function_t predicate,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1379 Lisp_Object hash_table, void *extra_arg)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1380 {
489
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1381 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
1382 Lisp_Object * const objs = copy_compress_hentries (ht);
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1383 const Lisp_Object *pobj, *end;
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1384 int speccount = specpdl_depth ();
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1385 struct gcpro gcpro1;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1386
489
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1387 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
1388 GCPRO1 (objs[0]);
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1389 gcpro1.nvars = 2 * ht->count;
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1390
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1391 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
1392 if (predicate (pobj[0], pobj[1], extra_arg))
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1393 Fremhash (pobj[0], hash_table);
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1394
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
1395 unbind_to (speccount);
489
4a8bb4aa9740 [xemacs-hg @ 2001-04-30 08:49:24 by martinb]
martinb
parents: 464
diff changeset
1396 UNGCPRO;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1397 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1398
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1399
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1400 /************************************************************************/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1401 /* garbage collecting weak hash tables */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1402 /************************************************************************/
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1403 #define MARK_OBJ(obj) do { \
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1404 Lisp_Object mo_obj = (obj); \
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1405 if (!marked_p (mo_obj)) \
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1406 { \
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1407 mark_object (mo_obj); \
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1408 did_mark = 1; \
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1409 } \
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1410 } while (0)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1411
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1412
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1413 /* Complete the marking for semi-weak hash tables. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1414 int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1415 finish_marking_weak_hash_tables (void)
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 Lisp_Object hash_table;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1418 int did_mark = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1419
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1420 for (hash_table = Vall_weak_hash_tables;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1421 !NILP (hash_table);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1422 hash_table = XHASH_TABLE (hash_table)->next_weak)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1423 {
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1424 const Lisp_Hash_Table *ht = XHASH_TABLE (hash_table);
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1425 const hentry *e = ht->hentries;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1426 const hentry *sentinel = e + ht->size;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1427
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1428 if (! marked_p (hash_table))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1429 /* The hash table is probably garbage. Ignore it. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1430 continue;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1431
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1432 /* Now, scan over all the pairs. For all pairs that are
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1433 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
1434 keeping this pair. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1435 switch (ht->weakness)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1436 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1437 case HASH_TABLE_KEY_WEAK:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1438 for (; e < sentinel; e++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1439 if (!HENTRY_CLEAR_P (e))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1440 if (marked_p (e->key))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1441 MARK_OBJ (e->value);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1442 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1443
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1444 case HASH_TABLE_VALUE_WEAK:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1445 for (; e < sentinel; e++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1446 if (!HENTRY_CLEAR_P (e))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1447 if (marked_p (e->value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1448 MARK_OBJ (e->key);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1449 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1450
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1451 case HASH_TABLE_KEY_VALUE_WEAK:
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1452 for (; e < sentinel; e++)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1453 if (!HENTRY_CLEAR_P (e))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1454 {
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1455 if (marked_p (e->value))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1456 MARK_OBJ (e->key);
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1457 else if (marked_p (e->key))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1458 MARK_OBJ (e->value);
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1459 }
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1460 break;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1461
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1462 case HASH_TABLE_KEY_CAR_WEAK:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1463 for (; e < sentinel; e++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1464 if (!HENTRY_CLEAR_P (e))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1465 if (!CONSP (e->key) || marked_p (XCAR (e->key)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1466 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1467 MARK_OBJ (e->key);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1468 MARK_OBJ (e->value);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1469 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1470 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1471
450
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
1472 /* We seem to be sprouting new weakness types at an alarming
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
1473 rate. At least this is not externally visible - and in
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
1474 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
1475 glyph code. */
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
1476 case HASH_TABLE_KEY_CAR_VALUE_WEAK:
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
1477 for (; e < sentinel; e++)
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
1478 if (!HENTRY_CLEAR_P (e))
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
1479 {
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
1480 if (!CONSP (e->key) || marked_p (XCAR (e->key)))
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
1481 {
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
1482 MARK_OBJ (e->key);
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
1483 MARK_OBJ (e->value);
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
1484 }
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
1485 else if (marked_p (e->value))
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
1486 MARK_OBJ (e->key);
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
1487 }
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
1488 break;
98528da0b7fc Import from CVS: tag r21-2-40
cvs
parents: 444
diff changeset
1489
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1490 case HASH_TABLE_VALUE_CAR_WEAK:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1491 for (; e < sentinel; e++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1492 if (!HENTRY_CLEAR_P (e))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1493 if (!CONSP (e->value) || marked_p (XCAR (e->value)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1494 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1495 MARK_OBJ (e->key);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1496 MARK_OBJ (e->value);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1497 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1498 break;
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 default:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1501 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1502 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1503 }
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 return did_mark;
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1508 void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1509 prune_weak_hash_tables (void)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1510 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1511 Lisp_Object hash_table, prev = Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1512 for (hash_table = Vall_weak_hash_tables;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1513 !NILP (hash_table);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1514 hash_table = XHASH_TABLE (hash_table)->next_weak)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1515 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1516 if (! marked_p (hash_table))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1517 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1518 /* This hash table itself is garbage. Remove it from the list. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1519 if (NILP (prev))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1520 Vall_weak_hash_tables = XHASH_TABLE (hash_table)->next_weak;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1521 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1522 XHASH_TABLE (prev)->next_weak = XHASH_TABLE (hash_table)->next_weak;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1523 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1524 else
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 /* Now, scan over all the pairs. Remove all of the pairs
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1527 in which the key or value, or both, is unmarked
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1528 (depending on the weakness of the hash table). */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1529 Lisp_Hash_Table *ht = XHASH_TABLE (hash_table);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1530 hentry *entries = ht->hentries;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1531 hentry *sentinel = entries + ht->size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1532 hentry *e;
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 for (e = entries; e < sentinel; e++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1535 if (!HENTRY_CLEAR_P (e))
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 again:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1538 if (!marked_p (e->key) || !marked_p (e->value))
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 remhash_1 (ht, entries, e);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1541 if (!HENTRY_CLEAR_P (e))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1542 goto again;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1543 }
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1546 prev = hash_table;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1547 }
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 }
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 /* 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
1552
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1553 Hashcode
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1554 internal_array_hash (Lisp_Object *arr, int size, int depth)
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 int i;
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1557 Hashcode hash = 0;
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1558 depth++;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1559
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1560 if (size <= 5)
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 for (i = 0; i < size; i++)
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1563 hash = HASH2 (hash, internal_hash (arr[i], depth));
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1564 return hash;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1565 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1566
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1567 /* just pick five elements scattered throughout the array.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1568 A slightly better approach would be to offset by some
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1569 noise factor from the points chosen below. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1570 for (i = 0; i < 5; i++)
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1571 hash = HASH2 (hash, internal_hash (arr[i*size/5], depth));
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1572
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1573 return hash;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1574 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1575
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1576 /* 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
1577 objects with the comparison being `equal' (for `eq', you can just
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1578 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
1579 tradeoff between the speed of the hash function and how good the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1580 hashing is. In particular, the hash function needs to be FAST,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1581 so you can't just traipse down the whole tree hashing everything
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1582 together. Most of the time, objects will differ in the first
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1583 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
1584 and only hash at most 5 elements out of a vector. Theoretically
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1585 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
1586 hash, but practically this won't ever happen. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1587
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1588 Hashcode
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1589 internal_hash (Lisp_Object obj, int depth)
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 if (depth > 5)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1592 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1593 if (CONSP (obj))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1594 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1595 /* no point in worrying about tail recursion, since we're not
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1596 going very deep */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1597 return HASH2 (internal_hash (XCAR (obj), depth + 1),
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1598 internal_hash (XCDR (obj), depth + 1));
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 if (STRINGP (obj))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1601 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1602 return hash_string (XSTRING_DATA (obj), XSTRING_LENGTH (obj));
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 if (LRECORDP (obj))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1605 {
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1606 const struct lrecord_implementation
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1607 *imp = XRECORD_LHEADER_IMPLEMENTATION (obj);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1608 if (imp->hash)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1609 return imp->hash (obj, depth);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1610 }
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 return LISP_HASH (obj);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1613 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1614
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1615 DEFUN ("sxhash", Fsxhash, 1, 1, 0, /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1616 Return a hash value for OBJECT.
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
1617 \(equal obj1 obj2) implies (= (sxhash obj1) (sxhash obj2)).
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1618 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1619 (object))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1620 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1621 return make_int (internal_hash (object, 0));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1622 }
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 #if 0
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1625 xxDEFUN ("internal-hash-value", Finternal_hash_value, 1, 1, 0, /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1626 Hash value of OBJECT. For debugging.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1627 The value is returned as (HIGH . LOW).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1628 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1629 (object))
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 /* This function is pretty 32bit-centric. */
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1632 Hashcode hash = internal_hash (object, 0);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1633 return Fcons (hash >> 16, hash & 0xffff);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1634 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1635 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1636
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1637
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1638 /************************************************************************/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1639 /* initialization */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1640 /************************************************************************/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1641
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1642 void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1643 syms_of_elhash (void)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1644 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1645 DEFSUBR (Fhash_table_p);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1646 DEFSUBR (Fmake_hash_table);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1647 DEFSUBR (Fcopy_hash_table);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1648 DEFSUBR (Fgethash);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1649 DEFSUBR (Fremhash);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1650 DEFSUBR (Fputhash);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1651 DEFSUBR (Fclrhash);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1652 DEFSUBR (Fmaphash);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1653 DEFSUBR (Fhash_table_count);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1654 DEFSUBR (Fhash_table_test);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1655 DEFSUBR (Fhash_table_size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1656 DEFSUBR (Fhash_table_rehash_size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1657 DEFSUBR (Fhash_table_rehash_threshold);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1658 DEFSUBR (Fhash_table_weakness);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1659 DEFSUBR (Fhash_table_type); /* obsolete */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1660 DEFSUBR (Fsxhash);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1661 #if 0
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1662 DEFSUBR (Finternal_hash_value);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1663 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1664
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1665 DEFSYMBOL_MULTIWORD_PREDICATE (Qhash_tablep);
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1666 DEFSYMBOL (Qhash_table);
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1667 DEFSYMBOL (Qhashtable);
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1668 DEFSYMBOL (Qweakness);
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1669 DEFSYMBOL (Qvalue);
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1670 DEFSYMBOL (Qkey_or_value);
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1671 DEFSYMBOL (Qkey_and_value);
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1672 DEFSYMBOL (Qrehash_size);
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1673 DEFSYMBOL (Qrehash_threshold);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1674
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1675 DEFSYMBOL (Qweak); /* obsolete */
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1676 DEFSYMBOL (Qkey_weak); /* obsolete */
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1677 DEFSYMBOL (Qkey_or_value_weak); /* obsolete */
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1678 DEFSYMBOL (Qvalue_weak); /* obsolete */
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1679 DEFSYMBOL (Qnon_weak); /* obsolete */
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1680
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1681 DEFKEYWORD (Q_test);
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1682 DEFKEYWORD (Q_size);
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1683 DEFKEYWORD (Q_rehash_size);
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1684 DEFKEYWORD (Q_rehash_threshold);
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1685 DEFKEYWORD (Q_weakness);
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 504
diff changeset
1686 DEFKEYWORD (Q_type); /* obsolete */
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1687 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1688
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1689 void
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
1690 init_elhash_once_early (void)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1691 {
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
1692 INIT_LRECORD_IMPLEMENTATION (hash_table);
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
1693
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1694 /* This must NOT be staticpro'd */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1695 Vall_weak_hash_tables = Qnil;
452
3d3049ae1304 Import from CVS: tag r21-2-41
cvs
parents: 450
diff changeset
1696 dump_add_weak_object_chain (&Vall_weak_hash_tables);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1697 }