From 543dab59640fa5e911443baaadaae471406dbf40 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 9 Aug 2020 15:48:22 -0600 Subject: [PATCH] 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 --- pkgs/racket-test-core/tests/racket/hash.rktl | 21 ++++++++++++++++++++ racket/src/cs/rumble/hash.ss | 6 +++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/hash.rktl b/pkgs/racket-test-core/tests/racket/hash.rktl index 83e5b9bcdda..286376921d1 100644 --- a/pkgs/racket-test-core/tests/racket/hash.rktl +++ b/pkgs/racket-test-core/tests/racket/hash.rktl @@ -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) diff --git a/racket/src/cs/rumble/hash.ss b/racket/src/cs/rumble/hash.ss index 3a0444c1d37..57febc70388 100644 --- a/racket/src/cs/rumble/hash.ss +++ b/racket/src/cs/rumble/hash.ss @@ -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)