2
Copyright (C) 1994 M. Hagiya, W. Schelter, T. Yuasa
4
This file is part of GNU Common Lisp, herein referred to as GCL
6
GCL is free software; you can redistribute it and/or modify it under
7
the terms of the GNU LIBRARY GENERAL PUBLIC LICENSE as published by
8
the Free Software Foundation; either version 2, or (at your option)
11
GCL is distributed in the hope that it will be useful, but WITHOUT
12
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
14
License for more details.
16
You should have received a copy of the GNU Library General Public License
17
along with GCL; see the file COPYING. If not, write to the Free Software
18
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
32
object sKrehash_threshold;
48
int l = mpz_size (mp);
49
mp_limb_t *u = mp->_mp_d;
69
return(hash_eql(x->rat.rat_num) + hash_eql(x->rat.rat_den));
72
return(*((int *) &(sf(x))));
75
{int *y = (int *) &lf(x);
76
return( *y + *(y+1));}
79
return(hash_eql(x->cmp.cmp_real) + hash_eql(x->cmp.cmp_imag));
85
return((unsigned long)x / 4);
101
if (depth++ >3) return h;
102
switch (type_of(x)) {
104
h += ihash_equal(x->c.c_car,depth);
109
for (i = x->st.st_fillp, s = x->st.st_self; i > 0; --i, s++)
110
h += (*s & 0377)*12345 + 1;
113
/* case t_string could share this code--wfs */
114
{int len=x->st.st_fillp;
119
case 4: h+= s[--len] << 24;
120
case 3: h+= s[--len]<< 16;
121
case 2: h+= s[1] << 8;
129
case t_package: return h;
141
/* 8 should be CHAR_SIZE but this needs to be changed
144
bzero(ar,sizeof(ar));
145
for (k = x->bv.bv_offset, j = 0; k < e; k++, j++)
146
if (x->bv.bv_self[k/8]&(0200>>k%8))
147
ar[j/8] |= 0200>>j%8;
149
for (; i > 0; --i, s++)
150
h += (*s & 0377)*12345 + 1;
155
h += ihash_equal(x->pn.pn_host,depth);
156
h += ihash_equal(x->pn.pn_device,depth);
157
h += ihash_equal(x->pn.pn_directory,depth);
158
h += ihash_equal(x->pn.pn_name,depth);
159
h += ihash_equal(x->pn.pn_type,depth);
160
h += ihash_equal(x->pn.pn_version,depth);
162
/* CLTLII says don't descend into structures
164
{unsigned char *s_type;
166
def=S_DATA(x->str.str_def);
167
s_type= & SLOT_TYPE(x->str.str_def,0);
168
h += ihash_equal(def->name,depth);
169
for (i = 0; i < def->length; i++)
171
h += ihash_equal(x->str.str_self[i],depth);
173
h += ((int)x->str.str_self[i]) + depth++;
178
return(h + hash_eql(x));
183
FFN(hash_equal)(x,depth)
188
return make_fixnum(ihash_equal(x,depth));
193
gethash(key, hashtable)
201
int i=0, j = -1, k; /* k added by chou */
204
htest = (enum httest)hashtable->ht.ht_test;
205
hsize = hashtable->ht.ht_size;
208
else if (htest == htt_eql)
210
else if (htest == htt_equal)
211
i = ihash_equal(key,0);
213
for (i %= hsize, k = 0; k < hsize; i = (i + 1) % hsize, k++) { /* k added by chou */
214
e = &hashtable->ht.ht_self[i];
216
if (hkey == OBJNULL) {
217
if (e->hte_value == OBJNULL)
221
return(&hashtable->ht.ht_self[j]);
226
/* this was never returning --wfs
227
but looping around with j=0 */
234
else if (htest == htt_eql)
236
else if (htest == htt_equal)
237
b = equal(key, hkey);
239
return(&hashtable->ht.ht_self[i]);
241
return(&hashtable->ht.ht_self[j]); /* added by chou */
245
extend_hashtable(object);
248
sethash(key, hashtable, value)
249
object key, hashtable, value;
255
i = hashtable->ht.ht_nent + 1;
256
if (type_of(hashtable->ht.ht_rhthresh) == t_fixnum)
257
over = i >= fix(hashtable->ht.ht_rhthresh);
258
else if (type_of(hashtable->ht.ht_rhthresh) == t_shortfloat)
260
i >= hashtable->ht.ht_size * sf(hashtable->ht.ht_rhthresh);
261
else if (type_of(hashtable->ht.ht_rhthresh) == t_longfloat)
263
i >= hashtable->ht.ht_size * lf(hashtable->ht.ht_rhthresh);
265
extend_hashtable(hashtable);
266
e = gethash(key, hashtable);
267
if (e->hte_key == OBJNULL)
268
hashtable->ht.ht_nent++;
270
e->hte_value = value;
274
extend_hashtable(hashtable)
280
if (type_of(hashtable->ht.ht_rhsize) == t_fixnum)
282
hashtable->ht.ht_size + fix(hashtable->ht.ht_rhsize);
283
else if (type_of(hashtable->ht.ht_rhsize) == t_shortfloat)
285
hashtable->ht.ht_size * sf(hashtable->ht.ht_rhsize);
286
else if (type_of(hashtable->ht.ht_rhsize) == t_longfloat)
288
hashtable->ht.ht_size * lf(hashtable->ht.ht_rhsize);
290
old = alloc_object(t_hashtable);
291
old->ht = hashtable->ht;
293
hashtable->ht.ht_self = NULL;
294
hashtable->ht.ht_size = new_size;
295
if (type_of(hashtable->ht.ht_rhthresh) == t_fixnum)
296
hashtable->ht.ht_rhthresh =
297
make_fixnum(fix(hashtable->ht.ht_rhthresh) +
298
(new_size - old->ht.ht_size));
299
hashtable->ht.ht_self =
300
(struct htent *)alloc_relblock(new_size * sizeof(struct htent));
301
for (i = 0; i < new_size; i++) {
302
hashtable->ht.ht_self[i].hte_key = OBJNULL;
303
hashtable->ht.ht_self[i].hte_value = OBJNULL;
305
for (i = 0; i < old->ht.ht_size; i++) {
306
if (old->ht.ht_self[i].hte_key != OBJNULL)
307
sethash(old->ht.ht_self[i].hte_key,
309
old->ht.ht_self[i].hte_value);
311
hashtable->ht.ht_nent = old->ht.ht_nent;
317
@(defun make_hash_table (&key (test sLeql)
318
(size `make_fixnum(1024)`)
320
`make_shortfloat((shortfloat)1.5)`)
322
`make_shortfloat((shortfloat)0.7)`)
327
if (test == sLeq || test == sLeq->s.s_gfdef)
329
else if (test == sLeql || test == sLeql->s.s_gfdef)
331
else if (test == sLequal || test == sLequal->s.s_gfdef)
334
FEerror("~S is an illegal hash-table test function.",
336
if (type_of(size) != t_fixnum || 0 < fix(size))
339
FEerror("~S is an illegal hash-table size.", 1, size);
340
if ((type_of(rehash_size) == t_fixnum && 0 < fix(rehash_size)) ||
341
(type_of(rehash_size) == t_shortfloat && 1.0 < sf(rehash_size)) ||
342
(type_of(rehash_size) == t_longfloat && 1.0 < lf(rehash_size)))
345
FEerror("~S is an illegal hash-table rehash-size.",
347
if ((type_of(rehash_threshold) == t_fixnum &&
348
0 < fix(rehash_threshold) && fix(rehash_threshold) < fix(size)) ||
349
(type_of(rehash_threshold) == t_shortfloat &&
350
0.0 < sf(rehash_threshold) && sf(rehash_threshold) < 1.0) ||
351
(type_of(rehash_threshold) == t_longfloat &&
352
0.0 < lf(rehash_threshold) && lf(rehash_threshold) < 1.0))
355
FEerror("~S is an illegal hash-table rehash-threshold.",
356
1, rehash_threshold);
358
h = alloc_object(t_hashtable);
359
h->ht.ht_test = (short)htt;
360
h->ht.ht_size = fix(size);
361
h->ht.ht_rhsize = rehash_size;
362
h->ht.ht_rhthresh = rehash_threshold;
364
h->ht.ht_self = NULL;
365
h->ht.ht_self = (struct htent *)
366
alloc_relblock(fix(size) * sizeof(struct htent));
367
for(i = 0; i < fix(size); i++) {
368
h->ht.ht_self[i].hte_key = OBJNULL;
369
h->ht.ht_self[i].hte_value = OBJNULL;
375
LFD(Lhash_table_p)(void)
379
if(type_of(vs_base[0]) == t_hashtable)
390
narg = vs_top - vs_base;
396
too_many_arguments();
397
check_type_hash_table(&vs_base[1]);
398
e = gethash(vs_base[0], vs_base[1]);
399
if (e->hte_key != OBJNULL) {
400
vs_base[0] = e->hte_value;
403
vs_base[0] = vs_base[2];
413
check_type_hash_table(&vs_base[1]);
414
sethash(vs_base[0], vs_base[1], vs_base[2]);
423
check_type_hash_table(&vs_base[1]);
424
e = gethash(vs_base[0], vs_base[1]);
425
if (e->hte_key != OBJNULL) {
426
e->hte_key = OBJNULL;
428
vs_base[1]->ht.ht_nent--;
432
vs_top = vs_base + 1;
440
check_type_hash_table(&vs_base[0]);
441
for(i = 0; i < vs_base[0]->ht.ht_size; i++) {
442
vs_base[0]->ht.ht_self[i].hte_key = OBJNULL;
443
vs_base[0]->ht.ht_self[i].hte_value = OBJNULL;
445
vs_base[0]->ht.ht_nent = 0;
448
LFD(Lhash_table_count)()
452
check_type_hash_table(&vs_base[0]);
453
vs_base[0] = make_fixnum(vs_base[0]->ht.ht_nent);
461
vs_base[0] = make_fixnum((ihash_equal(vs_base[0],0) & 0x7fffffff));
466
object *base = vs_base;
471
check_type_hash_table(&vs_base[1]);
472
hashtable = vs_base[1];
473
for (i = 0; i < hashtable->ht.ht_size; i++) {
474
if(hashtable->ht.ht_self[i].hte_key != OBJNULL)
476
hashtable->ht.ht_self[i].hte_key,
477
hashtable->ht.ht_self[i].hte_value);
483
DEFUN_NEW("NEXT-HASH-TABLE-ENTRY",object,fSnext_hash_table_entry,SI,2,2,NONE,OO,OO,OO,OO,(object table,object ind),"For HASH-TABLE and for index I return three values: NEXT-START, the next KEY and its VALUE. NEXT-START will be -1 if there are no more entries, otherwise it will be a value suitable for passing as an index")
485
check_type_hash_table(&table);
486
if ( i < 0) { FEerror("needs non negative index",0);}
487
while ( i < table->ht.ht_size) {
488
if (table->ht.ht_self[i].hte_key != OBJNULL) {
489
RETURN(3,object,make_fixnum(i+1),
490
(RV(table->ht.ht_self[i].hte_key),
491
RV(table->ht.ht_self[i].hte_value)));}
493
RETURN(3,object,small_fixnum(-1),(RV(sLnil),RV(sLnil)));
496
DEFUN_NEW("HASH-TABLE-TEST",object,fLhash_table_test,LISP,1,1,NONE,OO,OO,OO,OO,(object table),
497
"Given a HASH-TABLE return a symbol which specifies the function used in its test")
498
{ switch(table->ht.ht_test) {
499
case htt_equal: RETURN1(sLequal);
500
case htt_eq: RETURN1(sLeq);
501
case htt_eql: RETURN1(sLeql);
503
FEerror("not able to get hash table test for ~a",1,table);
507
DEFUN_NEW("HASH-TABLE-SIZE",object,fLhash_table_size,LISP,1,1,NONE,OO,OO,OO,OO,(object table),"")
509
RETURN1(make_fixnum(table->ht.ht_size));
518
sLeq = make_ordinary("EQ");
519
sLeql = make_ordinary("EQL");
520
sLequal = make_ordinary("EQUAL");
521
sKsize = make_keyword("SIZE");
522
sKtest = make_keyword("TEST");
523
sKrehash_size = make_keyword("REHASH-SIZE");
524
sKrehash_threshold = make_keyword("REHASH-THRESHOLD");
526
make_function("MAKE-HASH-TABLE", Lmake_hash_table);
527
make_function("HASH-TABLE-P", Lhash_table_p);
528
make_function("GETHASH", Lgethash);
529
make_function("REMHASH", Lremhash);
530
make_function("MAPHASH", Lmaphash);
531
make_function("CLRHASH", Lclrhash);
532
make_function("HASH-TABLE-COUNT", Lhash_table_count);
533
make_function("SXHASH", Lsxhash);
534
make_si_sfun("HASH-EQUAL",hash_equal,ARGTYPE2(f_object,f_fixnum)
535
| RESTYPE(f_object));
536
make_si_function("HASH-SET", siLhash_set);