cs: fix iteration on copy of a mutable hash table

Incorrect initialization of the copy's iteration state for a hash
table meant that table sizes larger than 32 looked like tables of only
32 elements when iterating (including when printing).

Closes #3344
This commit is contained in:
Matthew Flatt 2020-08-09 15:48:22 -06:00
parent 4f0290186b
commit 543dab5964
2 changed files with 24 additions and 3 deletions

View File

@ -577,6 +577,27 @@
(test 1 hash-count ht2)
(test #t eq? (car (hash-keys ht2)) g))
;; ----------------------------------------
;; Regression test to make sure all elements are still
;; reachable by iteration in a copy of a mutable hash table:
(let ([ht (make-hash)])
(for ([i 113])
(hash-set! ht i 1))
(define new-ht (hash-copy ht))
(test (hash-count ht) hash-count new-ht)
(test (for/sum ([k (in-hash-keys ht)])
k)
'sum
(for/sum ([k (in-hash-keys new-ht)])
k))
(test (hash-count ht)
'count
(for/sum ([v (in-hash-values new-ht)])
v)))
;; ----------------------------------------
(report-errs)

View File

@ -14,8 +14,8 @@
(define-record eq-mutable-hash mutable-hash
())
(define (create-mutable-hash ht kind) (make-mutable-hash (make-lock kind) #f #f ht))
(define (create-eq-mutable-hash ht) (make-eq-mutable-hash (make-lock 'eq?) #f #f ht))
(define (create-mutable-hash ht kind) (make-mutable-hash (make-lock kind) #f #t ht))
(define (create-eq-mutable-hash ht) (make-eq-mutable-hash (make-lock 'eq?) #f #t ht))
(define (mutable-hash-lock ht) (locked-iterable-hash-lock ht))
(define (mutable-hash-cells ht) (locked-iterable-hash-cells ht))
@ -654,7 +654,7 @@
0)
32))])
(let ([len (#%vector-length new-vec)])
(when (fx= len (hash-count ht))<
(when (fx= len (hash-count ht))
(set-locked-iterable-hash-retry?! ht #f)))
(let ([vec (cells-merge vec new-vec)])
(set-locked-iterable-hash-cells! ht vec)