made cons hashing tail recursive on cdrs
plus one more test
This commit is contained in:
parent
ff650e3049
commit
99c17feac1
|
@ -308,21 +308,24 @@ static uptrint_t bounded_hash(value_t a, int bound, int *oob)
|
|||
return h;
|
||||
|
||||
case TAG_CONS:
|
||||
do {
|
||||
if (bound <= 0) {
|
||||
*oob = 1;
|
||||
return 1;
|
||||
return h;
|
||||
}
|
||||
h = bounded_hash(car_(a), bound/2, oob);
|
||||
h = MIX(h, bounded_hash(car_(a), bound/2, &oob2));
|
||||
// bounds balancing: try to share the bounds efficiently
|
||||
// between the car and cdr so we can hash better when a list is
|
||||
// car-shallow and cdr-deep (a common case) or vice-versa.
|
||||
if (*oob)
|
||||
// so we can hash better when a list is cdr-deep (a common case)
|
||||
if (oob2)
|
||||
bound/=2;
|
||||
else
|
||||
bound--;
|
||||
h = MIX(h, bounded_hash(cdr_(a), bound, &oob2)+2);
|
||||
// recursive OOB propagation. otherwise this case is slow:
|
||||
// (hash '#2=('#0=(#1=(#1#) . #0#) . #2#))
|
||||
// (hash '#2=((#0=(#1=(#1#) . #0#)) . #2#))
|
||||
*oob = *oob || oob2;
|
||||
a = cdr_(a);
|
||||
} while (iscons(a));
|
||||
h = MIX(h, bounded_hash(a, bound-1, &oob2)+2);
|
||||
*oob = *oob || oob2;
|
||||
return h;
|
||||
}
|
||||
|
|
|
@ -130,6 +130,14 @@
|
|||
(hash '#0=((1 . #0#) . #0#))
|
||||
(hash '#1=((1 . #1#) (2 . #1#) . #1#)))))
|
||||
|
||||
(assert (equal?
|
||||
(hash '(#0=(#0#) 0))
|
||||
(hash '(#1=(((((#1#))))) 0))))
|
||||
|
||||
(assert (not (equal?
|
||||
(hash '(#0=(#0#) 0))
|
||||
(hash '(#1=(((((#1#))))) 1)))))
|
||||
|
||||
(assert (equal?
|
||||
(hash #0=[1 [2 [#0#]] 3])
|
||||
(hash #1=[1 [2 [[1 [2 [#1#]] 3]]] 3])))
|
||||
|
|
Loading…
Reference in New Issue