repair for hash-keys-subset?
When comparing a part of a hamt that is a collision node versus a subtree node, a "hash code" was extracted from the collision node --- but that's really a code for an integer key is that used for the collision element. The comparison should instead use a code extracted from the reference to the collision node (which is the code that is common to all colliding keys).
This commit is contained in:
parent
f8aeed279b
commit
6de3659664
|
@ -35,6 +35,44 @@
|
|||
#hash([one . 1] [two . 2] [three . 3] [four . 4]))
|
||||
h))
|
||||
|
||||
(let ()
|
||||
(struct a (n m)
|
||||
#:property
|
||||
prop:equal+hash
|
||||
(list (lambda (a b eql) (and (= (a-n a) (a-n b))
|
||||
(= (a-m a) (a-m b))))
|
||||
(lambda (a hc) (a-n a))
|
||||
(lambda (a hc) (a-n a))))
|
||||
|
||||
(define ht0 (hash (a 1 0) #t))
|
||||
;; A hash table with two keys that have the same hash code
|
||||
(define ht1 (hash (a 1 0) #t
|
||||
(a 1 2) #t))
|
||||
;; Another hash table with the same two keys, plus another
|
||||
;; with an extra key whose hash code is different but the
|
||||
;; same in the last 5 bits:
|
||||
(define ht2 (hash (a 1 0) #t
|
||||
(a 1 2) #t
|
||||
(a 33 0) #t))
|
||||
;; A hash table with no collision, but the same last
|
||||
;; 5 bits for both keys:
|
||||
(define ht3 (hash (a 1 0) #t
|
||||
(a 33 0) #t))
|
||||
|
||||
;; Subset must compare a collision node with a subtree node (that
|
||||
;; contains a collision node):
|
||||
(test #t hash-keys-subset? ht1 ht2)
|
||||
|
||||
(test #t hash-keys-subset? ht3 ht2)
|
||||
(test #t hash-keys-subset? ht0 ht3)
|
||||
|
||||
(test #t hash-keys-subset? ht0 ht2)
|
||||
(test #t hash-keys-subset? ht0 ht1)
|
||||
(test #f hash-keys-subset? ht2 ht1)
|
||||
(test #f hash-keys-subset? ht2 ht0)
|
||||
(test #f hash-keys-subset? ht1 ht0)
|
||||
(test #f hash-keys-subset? ht1 ht3))
|
||||
|
||||
(let ()
|
||||
(define-syntax (define-hash-iterations-tester stx)
|
||||
(syntax-case stx ()
|
||||
|
|
|
@ -89,9 +89,10 @@ HAMT_NONGCING int HAMT_SUBSET_OF(Scheme_Hash_Tree *t1, Scheme_Hash_Tree *t2, int
|
|||
|
||||
if (HASHTR_SUBTREEP(k2)) {
|
||||
/* check each element of collision */
|
||||
uintptr_t code;
|
||||
code = _mzHAMT_CODE(t1, pos1, popcount1);
|
||||
for (i = ((Scheme_Hash_Tree *)k1)->count; i--; ) {
|
||||
uintptr_t code;
|
||||
hamt_at_index(((Scheme_Hash_Tree *)k1), i, &key, HAMT_IF_VAL(&val, NULL), &code);
|
||||
hamt_at_index(((Scheme_Hash_Tree *)k1), i, &key, HAMT_IF_VAL(&val, NULL), NULL);
|
||||
if (!HAMT_ELEMENT_OF(key, HAMT_IF_VAL(val, NULL), code,
|
||||
(Scheme_Hash_Tree *)k2,
|
||||
shift + mzHAMT_LOG_WORD_SIZE,
|
||||
|
|
Loading…
Reference in New Issue
Block a user