1;;; hash.ms 2;;; Copyright 1984-2017 Cisco Systems, Inc. 3;;; 4;;; Licensed under the Apache License, Version 2.0 (the "License"); 5;;; you may not use this file except in compliance with the License. 6;;; You may obtain a copy of the License at 7;;; 8;;; http://www.apache.org/licenses/LICENSE-2.0 9;;; 10;;; Unless required by applicable law or agreed to in writing, software 11;;; distributed under the License is distributed on an "AS IS" BASIS, 12;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13;;; See the License for the specific language governing permissions and 14;;; limitations under the License. 15 16(mat old-hash-table 17 (error? (get-hash-table '((a . b)) 'a #f)) 18 (error? (put-hash-table! (list (cons 'a 'b)) 'a 'b)) 19 (error? (remove-hash-table! (list (cons 'a 'b)) 'a)) 20 (error? (hash-table-map '((a . b)) cons)) 21 (error? (hash-table-for-each '((a . b)) cons)) 22 (begin 23 (define $h-ht (make-hash-table)) 24 (hash-table? $h-ht)) 25 (not (hash-table? 3)) 26 (not (hash-table? '$h-ht)) 27 (null? (hash-table-map $h-ht list)) 28 (eq? (let ([n 0]) 29 (hash-table-for-each $h-ht (lambda (x y) (set! n (+ n 1)))) 30 n) 31 0) 32 (equal? 33 (begin 34 (put-hash-table! $h-ht 'ham 'spam) 35 (hash-table-map $h-ht list)) 36 '((ham spam))) 37 (error? ; wrong number of args 38 (hash-table-map $h-ht (lambda (x) x))) 39 (error? ; wrong number of args 40 (hash-table-for-each $h-ht (lambda (x) x))) 41 ((lambda (x y) (or (equal? x y) (equal? x (reverse y)))) 42 (begin 43 (put-hash-table! $h-ht 'cram 'sham) 44 (hash-table-map $h-ht list)) 45 '((ham spam) (cram sham))) 46 ((lambda (x y) (or (equal? x y) (equal? x (reverse y)))) 47 (begin 48 (put-hash-table! $h-ht 'ham 'jam) 49 (hash-table-map $h-ht list)) 50 '((ham jam) (cram sham))) 51 (eq? (get-hash-table $h-ht 'ham #f) 'jam) 52 (eq? (get-hash-table $h-ht 'cram #f) 'sham) 53 (eq? (get-hash-table $h-ht 'sham #f) #f) 54 (equal? (get-hash-table $h-ht 'jam "rats") "rats") 55 (eq? (let ([n 0]) 56 (hash-table-for-each $h-ht (lambda (x y) (set! n (+ n 1)))) 57 n) 58 2) 59 ((lambda (x y) (or (equal? x y) (equal? x (reverse y)))) 60 (let ([keys '()] [vals '()]) 61 (hash-table-for-each $h-ht 62 (lambda (k v) 63 (set! keys (cons k keys)) 64 (set! vals (cons v vals)))) 65 (map cons vals keys)) 66 '((jam . ham) (sham . cram))) 67 (eq? (collect (collect-maximum-generation)) (void)) 68 ((lambda (x y) (or (equal? x y) (equal? x (reverse y)))) 69 (let ([keys '()] [vals '()]) 70 (hash-table-for-each $h-ht 71 (lambda (k v) 72 (set! keys (cons k keys)) 73 (set! vals (cons v vals)))) 74 (map cons vals keys)) 75 '((jam . ham) (sham . cram))) 76 (eq? (begin 77 (remove-hash-table! $h-ht 'ham) 78 (get-hash-table $h-ht 'ham 'gone!)) 79 'gone!) 80 (equal? 81 (hash-table-map $h-ht list) 82 '((cram sham))) 83 (eq? (collect (collect-maximum-generation)) (void)) 84 (equal? 85 (hash-table-map $h-ht list) 86 '((cram sham))) 87 (eq? (begin 88 (remove-hash-table! $h-ht 'ham) 89 (get-hash-table $h-ht 'ham 'gone!)) 90 'gone!) 91 (equal? 92 (hash-table-map $h-ht list) 93 '((cram sham))) 94 (eq? (begin 95 (remove-hash-table! $h-ht 'sham) 96 (get-hash-table $h-ht 'ham 'never-there!)) 97 'never-there!) 98 (equal? 99 (hash-table-map $h-ht list) 100 '((cram sham))) 101 (eq? (begin 102 (remove-hash-table! $h-ht 'cram) 103 (get-hash-table $h-ht 'cram 'gone-too!)) 104 'gone-too!) 105 (null? (hash-table-map $h-ht list)) 106 107 ; fasling out eq hash tables 108 (equal? 109 (let ([x (cons 'y '!)]) 110 (define ht (make-hash-table)) 111 (put-hash-table! ht x 'because) 112 (put-hash-table! ht 'foo "foo") 113 (let ([p (open-file-output-port "testfile.ss" (file-options replace))]) 114 (fasl-write (list x ht) p) 115 (close-port p)) 116 (let-values ([(x2 ht2) 117 (apply values 118 (call-with-port 119 (open-file-input-port "testfile.ss") 120 fasl-read))]) 121 (list 122 (get-hash-table ht2 x2 #f) 123 (get-hash-table ht2 'foo #f)))) 124 '(because "foo")) 125 126 ; weak hash table tests 127 (begin 128 (define $h-ht (make-hash-table #t)) 129 (hash-table? $h-ht)) 130 (null? 131 (begin 132 (put-hash-table! $h-ht (string #\a) 'yea!) 133 (collect (collect-maximum-generation)) 134 (hash-table-map $h-ht cons))) 135 (eq? (let ([n 0]) 136 (hash-table-for-each $h-ht (lambda (x y) (set! n (+ n 1)))) 137 n) 138 0) 139 (let ([s (string #\a)]) 140 (put-hash-table! $h-ht s 666) 141 (equal? (get-hash-table $h-ht s #f) 666)) 142 (null? 143 (begin 144 (collect (collect-maximum-generation)) 145 (hash-table-map $h-ht cons))) 146 147 ; make sure that nonweak hash tables are nonweak (explicit #f arg) 148 (begin 149 (define $h-ht (make-hash-table #f)) 150 (hash-table? $h-ht)) 151 (equal? 152 (begin 153 (put-hash-table! $h-ht (string #\a) "bc") 154 (collect (collect-maximum-generation)) 155 (hash-table-map $h-ht string-append)) 156 '("abc")) 157 158 ; make sure that nonweak hash tables are nonweak (implicit #f arg) 159 (begin 160 (define $h-ht (make-hash-table)) 161 (hash-table? $h-ht)) 162 (equal? 163 (begin 164 (put-hash-table! $h-ht (string #\a) "bc") 165 (collect (collect-maximum-generation)) 166 (hash-table-map $h-ht string-append)) 167 '("abc")) 168 169 ; stress tests 170 (let () ; nonweak 171 (define pick 172 (lambda (ls) 173 (list-ref ls (random (length ls))))) 174 (define ht (make-hash-table)) 175 (let* ([ls (remq '|| (oblist))] [n 50000]) 176 (let f ([i 0] [keep '()] [drop '()]) 177 (if (= i n) 178 (and (= (length (hash-table-map ht (lambda (x y) x))) 179 (- n (length drop))) 180 (andmap (lambda (k) 181 (string=? 182 (symbol->string (get-hash-table ht k #f)) 183 (cond 184 [(string? k) k] 185 [(pair? k) (car k)] 186 [(vector? k) (vector-ref k 0)]))) 187 keep) 188 (andmap (lambda (k) (eq? (get-hash-table ht k 'no) 'no)) 189 drop)) 190 (let* ([x (pick ls)] [s (string-copy (symbol->string x))]) 191 (let ([k (case (pick '(string pair vector)) 192 [(string) s] 193 [(pair) (list s)] 194 [(vector) (vector s)])]) 195 (put-hash-table! ht k x) 196 (let ([keep (if (= (modulo i 5) 0) (cons k keep) keep)]) 197 (if (= (modulo i 17) 5) 198 (let ([k (pick keep)]) 199 (remove-hash-table! ht k) 200 (let ([drop (cons k drop)]) 201 (when (= (random 5) 3) 202 (remove-hash-table! ht (pick drop))) 203 (f (+ i 1) (remq k keep) drop))) 204 (f (+ i 1) keep drop))))))))) 205 206 (let () ; weak 207 (define pick 208 (lambda (ls) 209 (list-ref ls (random (length ls))))) 210 (define ht (make-hash-table #t)) 211 (let* ([ls (remq '|| (oblist))] [n 50000]) 212 (let f ([i 0] [keep '()] [drop '()]) 213 (if (= i n) 214 (and (<= (length (hash-table-map ht (lambda (x y) x))) 215 (- n (length drop))) 216 (begin 217 (collect (collect-maximum-generation)) 218 (= (length (hash-table-map ht (lambda (x y) x))) 219 (length keep))) 220 (andmap (lambda (k) 221 (string=? 222 (symbol->string (get-hash-table ht k #f)) 223 (cond 224 [(string? k) k] 225 [(pair? k) (car k)] 226 [(vector? k) (vector-ref k 0)]))) 227 keep) 228 (andmap (lambda (k) (eq? (get-hash-table ht k 'no) 'no)) 229 drop)) 230 (let* ([x (pick ls)] [s (string-copy (symbol->string x))]) 231 (let ([k (case (pick '(string pair vector)) 232 [(string) s] 233 [(pair) (list s)] 234 [(vector) (vector s)])]) 235 (put-hash-table! ht k x) 236 (let ([keep (if (= (modulo i 5) 0) (cons k keep) keep)]) 237 (if (= (modulo i 17) 5) 238 (let ([k (pick keep)]) 239 (remove-hash-table! ht k) 240 (let ([drop (cons k drop)]) 241 (when (= (random 5) 3) 242 (remove-hash-table! ht (pick drop))) 243 (f (+ i 1) (remq k keep) drop))) 244 (f (+ i 1) keep drop))))))))) 245) 246 247(mat tlc 248 (critical-section 249 (let () 250 (define ht (make-eq-hashtable)) 251 (define keyval '(a . b)) 252 (define next 0) 253 (define tlc (#%$make-tlc ht keyval next)) 254 (define tlc2 (#%$make-tlc ht keyval next)) 255 (and 256 (#%$tlc? tlc) 257 (not (#%$tlc? keyval)) 258 (eq? (#%$tlc-ht tlc) ht) 259 (eq? (#%$tlc-keyval tlc) keyval) 260 (eqv? (#%$tlc-next tlc) next) 261 (begin 262 (#%$set-tlc-next! tlc tlc2) 263 (eq? (#%$tlc-next tlc) tlc2))))) 264) 265 266(define $vector-andmap 267 (lambda (p . v*) 268 (apply andmap p (map vector->list v*)))) 269 270(define $vector-append 271 (lambda v* 272 (list->vector (apply append (map vector->list v*))))) 273 274(define $vector-member? 275 (lambda (x v) 276 (let ([n (vector-length v)]) 277 (let f ([i 0]) 278 (and (not (fx= i n)) 279 (or (equal? (vector-ref v i) x) 280 (f (fx+ i 1)))))))) 281 282(define same-elements? 283 (lambda (v1 v2) 284 (let ([n (vector-length v1)]) 285 (define (each-in? v1 v2) 286 (let f ([i 0]) 287 (or (fx= i n) 288 (and ($vector-member? (vector-ref v1 i) v2) 289 (f (fx+ i 1)))))) 290 (and (fx= (vector-length v2) n) 291 (each-in? v1 v2) 292 (each-in? v2 v1))))) 293 294(define equal-entries? 295 (lambda (ht keys vals) 296 (define-syntax same-entries? 297 (syntax-rules () 298 [(_ e1 keys2 vals2) 299 (let-values ([(keys1 vals1) e1]) 300 (and 301 (same-elements? keys1 keys2) 302 (same-elements? vals1 vals2)))])) 303 304 (and 305 (same-elements? (hashtable-keys ht) keys) 306 (same-elements? (hashtable-values ht) vals) 307 (same-entries? (hashtable-entries ht) keys vals) 308 (same-elements? (hashtable-cells ht) (vector-map cons keys vals)) 309 310 (same-elements? (r6rs:hashtable-keys ht) keys) 311 (same-entries? (r6rs:hashtable-entries ht) keys vals) 312 313 ;; Check requested sizes > hash table size 314 (andmap (lambda (size) 315 (and 316 (same-elements? (hashtable-keys ht size) keys) 317 (same-elements? (hashtable-values ht size) vals) 318 (same-entries? (hashtable-entries ht size) keys vals) 319 (same-elements? (hashtable-cells ht size) (vector-map cons keys vals)))) 320 (list (add1 (hashtable-size ht)) 321 (expt 2 1000))) 322 323 ;; Make sure request of 0 always works: 324 (same-elements? (hashtable-keys ht 0) '#()) 325 (same-elements? (hashtable-values ht 0) '#()) 326 (same-entries? (hashtable-entries ht 0) '#() '#()) 327 (same-elements? (hashtable-cells ht 0) '#()) 328 329 (or 330 (< (hashtable-size ht) 2) 331 ;; Check request of size 2: 332 (let ([twos (lambda (v) 333 (let i-loop ([i 0]) 334 (cond 335 [(= i (vector-length v)) 336 '()] 337 [else 338 (let j-loop ([j (add1 i)]) 339 (cond 340 [(= j (vector-length v)) 341 (i-loop (add1 i))] 342 [else 343 (cons (vector (vector-ref v i) (vector-ref v j)) 344 (j-loop (add1 j)))]))])))]) 345 (let ([keyss (twos keys)] 346 [valss (twos vals)]) 347 (and 348 (let ([got-keys (hashtable-keys ht 2)]) 349 (ormap (lambda (keys) 350 (same-elements? got-keys keys)) 351 keyss)) 352 (let ([got-vals (hashtable-values ht 2)]) 353 (ormap (lambda (vals) 354 (same-elements? got-vals vals)) 355 valss)) 356 (let-values ([(got-keys got-vals) (hashtable-entries ht 2)]) 357 (ormap (lambda (keys vals) 358 (and (same-elements? got-keys keys) 359 (same-elements? got-vals vals))) 360 keyss valss)) 361 (let ([got-cells (hashtable-cells ht 2)]) 362 (ormap (lambda (keys vals) 363 (same-elements? got-cells (vector-map cons keys vals))) 364 keyss valss))))))))) 365 366(mat hashtable-arguments 367 ; make-eq-hashtable 368 (error? ; wrong argument count 369 (make-eq-hashtable 3 #t)) 370 (error? ; invalid size 371 (make-eq-hashtable -1)) 372 (error? ; invalid size 373 (make-eq-hashtable #t)) 374 (error? ; invalid size 375 (make-eq-hashtable #f)) 376 ; make-hashtable 377 (error? ; wrong argument count 378 (make-hashtable)) 379 (error? ; wrong argument count 380 (make-hashtable equal-hash)) 381 (error? ; wrong argument count 382 (make-hashtable equal-hash equal? 45 53)) 383 (error? ; not a procedure 384 (make-hashtable 'a equal? 45)) 385 (error? ; not a procedure 386 (make-hashtable equal-hash 'a 45)) 387 (error? ; invalid size 388 (make-hashtable equal-hash equal? 'a)) 389 (error? ; invalid size 390 (make-hashtable equal-hash equal? -45)) 391 (error? ; invalid size 392 (make-hashtable equal-hash equal? 45.0)) 393 ; make-eqv-hashtable 394 (error? ; wrong argument count 395 (make-eqv-hashtable 3 #t)) 396 (error? ; invalid size 397 (make-eqv-hashtable -1)) 398 (error? ; invalid size 399 (make-eqv-hashtable #t)) 400 (error? ; invalid size 401 (make-eqv-hashtable #f)) 402 (begin 403 (define $ht (make-eq-hashtable)) 404 (define $imht (hashtable-copy $ht)) 405 (define $ht2 (make-eq-hashtable 50)) 406 (and (hashtable? $ht) 407 (eq-hashtable? $ht) 408 (hashtable-mutable? $ht) 409 (not (hashtable-weak? $ht)) 410 (not (eq-hashtable-weak? $ht)) 411 (not (hashtable-ephemeron? $ht)) 412 (not (eq-hashtable-ephemeron? $ht)) 413 (hashtable? $imht) 414 (eq-hashtable? $imht) 415 (not (hashtable-mutable? $imht)) 416 (not (hashtable-weak? $imht)) 417 (not (eq-hashtable-weak? $imht)) 418 (not (hashtable-ephemeron? $imht)) 419 (not (eq-hashtable-ephemeron? $imht)) 420 (hashtable? $ht2) 421 (eq-hashtable? $ht2) 422 (hashtable-mutable? $ht2) 423 (not (hashtable-weak? $ht2)) 424 (not (eq-hashtable-weak? $ht2)) 425 (not (hashtable-ephemeron? $ht2)) 426 (not (eq-hashtable-ephemeron? $ht2)))) 427 (not (hashtable? 3)) 428 (not (hashtable? (make-vector 3))) 429 (not (eq-hashtable? 3)) 430 (not (eq-hashtable? (make-vector 3))) 431 ; hashtable? 432 (error? ; wrong argument count 433 (hashtable?)) 434 (error? ; wrong argument count 435 (hashtable? $ht 3)) 436 (error? ; wrong argument count 437 (eq-hashtable?)) 438 (error? ; wrong argument count 439 (eq-hashtable? $ht 3)) 440 ; hashtable-mutable? 441 (error? ; not a hashtable 442 (hashtable-mutable? (make-vector 3))) 443 (error? ; wrong argument count 444 (hashtable-mutable?)) 445 (error? ; wrong argument count 446 (hashtable-mutable? $ht 3)) 447 ; hashtable-size 448 (error? ; wrong argument count 449 (hashtable-size)) 450 (error? ; wrong argument count 451 (hashtable-size $ht 3)) 452 (error? ; not a hashtable 453 (hashtable-size 'hello)) 454 ; hashtable-ref 455 (error? ; wrong argument count 456 (hashtable-ref)) 457 (error? ; wrong argument count 458 (hashtable-ref $ht)) 459 (error? ; wrong argument count 460 (hashtable-ref $ht 'a)) 461 (error? ; wrong argument count 462 (hashtable-ref $ht 'a 'b 'c)) 463 (error? ; not a hashtable 464 (hashtable-ref '(hash . table) 'a 'b)) 465 ; hashtable-contains? 466 (error? ; wrong argument count 467 (hashtable-contains?)) 468 (error? ; wrong argument count 469 (hashtable-contains? $ht)) 470 (error? ; wrong argument count 471 (hashtable-contains? $ht 'a 'b)) 472 (error? ; not a hashtable 473 (hashtable-contains? '(hash . table) 'a)) 474 ; hashtable-set! 475 (error? ; wrong argument count 476 (hashtable-set!)) 477 (error? ; wrong argument count 478 (hashtable-set! $ht)) 479 (error? ; wrong argument count 480 (hashtable-set! $ht 'a)) 481 (error? ; wrong argument count 482 (hashtable-set! $ht 'a 'b 'c)) 483 (error? ; not a hashtable 484 (hashtable-set! '(hash . table) 'a 'b)) 485 (error? ; hashtable not mutable 486 (hashtable-set! $imht 'a 'b)) 487 ; hashtable-update! 488 (error? ; wrong argument count 489 (hashtable-update!)) 490 (error? ; wrong argument count 491 (hashtable-update! $ht)) 492 (error? ; wrong argument count 493 (hashtable-update! $ht 'a values)) 494 (error? ; wrong argument count 495 (hashtable-update! $ht 'a values 'c 'd)) 496 (error? ; not a hashtable 497 (hashtable-update! '(hash . table) 'a values 'b)) 498 (error? ; hashtable not mutable 499 (hashtable-update! $imht 'a values 'b)) 500 (error? ; not a procedure 501 (hashtable-update! $ht 'a "not a procedure" 'b)) 502 ; hashtable-cell 503 (error? ; wrong argument count 504 (hashtable-cell)) 505 (error? ; wrong argument count 506 (hashtable-cell $ht)) 507 (error? ; wrong argument count 508 (hashtable-cell $ht 'a)) 509 (error? ; wrong argument count 510 (hashtable-cell $ht 'a 'b 'c)) 511 (error? ; not a hashtable 512 (hashtable-cell '(hash . table) 'a 'b)) 513 ; hashtable-delete! 514 (error? ; wrong argument count 515 (hashtable-delete!)) 516 (error? ; wrong argument count 517 (hashtable-delete! $ht)) 518 (error? ; wrong argument count 519 (hashtable-delete! $ht 'a 'b)) 520 (error? ; not a hashtable 521 (hashtable-delete! '(hash . table) 'a)) 522 (error? ; hashtable not mutable 523 (hashtable-delete! $imht 'a)) 524 ; hashtable-copy 525 (error? ; wrong argument count 526 (hashtable-copy)) 527 (error? ; wrong argument count 528 (hashtable-copy $ht #t 17)) 529 (error? ; not a hashtable 530 (hashtable-copy '(hash . table) #t)) 531 ; hashtable-clear! 532 (error? ; wrong argument count 533 (hashtable-clear!)) 534 (error? ; wrong argument count 535 (hashtable-clear! $ht 17 'foo)) 536 (error? ; not a hashtable 537 (hashtable-clear! '(hash . table))) 538 (error? ; not a hashtable 539 (hashtable-clear! '(hash . table) 17)) 540 (error? ; hashtable not mutable 541 (hashtable-clear! $imht)) 542 (error? ; hashtable not mutable 543 (hashtable-clear! $imht 32)) 544 (error? ; invalid size 545 (hashtable-clear! $ht #t)) 546 ; hashtable-keys 547 (error? ; wrong argument count 548 (hashtable-keys)) 549 (error? ; wrong argument count 550 (hashtable-keys $ht 72 43)) 551 (error? ; not a hashtable 552 (hashtable-keys '(hash . table))) 553 (error? ; bad size 554 (hashtable-keys $ht -79)) 555 (error? ; bad size 556 (hashtable-keys $ht 'not-an-unsigned-integer)) 557 (error? ; wrong argument count 558 (r6rs:hashtable-keys)) 559 (error? ; wrong argument count 560 (r6rs:hashtable-keys $ht 72)) 561 (error? ; not a hashtable 562 (r6rs:hashtable-keys '(hash . table))) 563 ; hashtable-values 564 (error? ; wrong argument count 565 (hashtable-values)) 566 (error? ; wrong argument count 567 (hashtable-values $ht 72 43)) 568 (error? ; not a hashtable 569 (hashtable-values '(hash . table))) 570 (error? ; bad size 571 (hashtable-values $ht -79)) 572 (error? ; bad size 573 (hashtable-values $ht 'not-an-unsigned-integer)) 574 ; hashtable-entries 575 (error? ; wrong argument count 576 (hashtable-entries)) 577 (error? ; wrong argument count 578 (hashtable-entries $ht 72 43)) 579 (error? ; not a hashtable 580 (hashtable-entries '(hash . table))) 581 (error? ; bad size 582 (hashtable-entries $ht -79)) 583 (error? ; bad size 584 (hashtable-entries $ht 'not-an-unsigned-integer)) 585 (error? ; wrong argument count 586 (r6rs:hashtable-entries)) 587 (error? ; wrong argument count 588 (r6rs:hashtable-entries $ht 72)) 589 (error? ; not a hashtable 590 (r6rs:hashtable-entries '(hash . table))) 591 ; hashtable-cells 592 (error? ; wrong argument count 593 (hashtable-cells)) 594 (error? ; wrong argument count 595 (hashtable-cells $ht 72 43)) 596 (error? ; not a hashtable 597 (hashtable-cells '(hash . table))) 598 (error? ; bad size 599 (hashtable-cells $ht -79)) 600 (error? ; bad size 601 (hashtable-cells $ht 'not-an-unsigned-integer)) 602 ; hashtable-hash-function 603 (error? ; wrong argument count 604 (hashtable-hash-function)) 605 (error? ; wrong argument count 606 (hashtable-hash-function $ht $ht)) 607 (error? ; not a hsshtable 608 (hashtable-hash-function '(hash . table))) 609 ; hashtable-equivalence-function 610 (error? ; wrong argument count 611 (hashtable-equivalence-function)) 612 (error? ; wrong argument count 613 (hashtable-equivalence-function $ht $ht)) 614 (error? ; not a hsshtable 615 (hashtable-equivalence-function '(hash . table))) 616 ; hashtable-weak? 617 (error? ; wrong argument count 618 (hashtable-weak?)) 619 (error? ; wrong argument count 620 (hashtable-weak? $ht 3)) 621 (error? ; not a hashtable 622 (hashtable-weak? '(hash . table))) 623 ; hashtable-ephemeron? 624 (error? ; wrong argument count 625 (hashtable-ephemeron?)) 626 (error? ; wrong argument count 627 (hashtable-ephemeron? $ht 3)) 628 (error? ; not a hashtable 629 (hashtable-ephemeron? '(hash . table))) 630) 631 632(mat hash-return-value 633 ; hashtable-ref 634 (error? ; invalid hash-function return value 635 (let ([ht (make-hashtable (lambda (x) "oops") equal?)]) 636 (hashtable-ref ht 'any #f))) 637 #;(error? ; invalid hash-function return value 638 (let ([ht (make-hashtable (lambda (x) -7) equal?)]) 639 (hashtable-ref ht 'any #f))) 640 (error? ; invalid hash-function return value 641 (let ([ht (make-hashtable (lambda (x) 3.5) equal?)]) 642 (hashtable-ref ht 'any #f))) 643 (error? ; invalid hash-function return value 644 (let ([ht (make-hashtable (lambda (x) 1+2i) equal?)]) 645 (hashtable-ref ht 'any #f))) 646 ; hashtable-contains? 647 (error? ; invalid hash-function return value 648 (let ([ht (make-hashtable (lambda (x) "oops") equal?)]) 649 (hashtable-contains? ht 'any))) 650 #;(error? ; invalid hash-function return value 651 (let ([ht (make-hashtable (lambda (x) -7) equal?)]) 652 (hashtable-contains? ht 'any))) 653 (error? ; invalid hash-function return value 654 (let ([ht (make-hashtable (lambda (x) 3.5) equal?)]) 655 (hashtable-contains? ht 'any))) 656 (error? ; invalid hash-function return value 657 (let ([ht (make-hashtable (lambda (x) 1+2i) equal?)]) 658 (hashtable-contains? ht 'any))) 659 ; hashtable-set! 660 (error? ; invalid hash-function return value 661 (let ([ht (make-hashtable (lambda (x) "oops") equal?)]) 662 (hashtable-set! ht 'any 'spam))) 663 #;(error? ; invalid hash-function return value 664 (let ([ht (make-hashtable (lambda (x) -7) equal?)]) 665 (hashtable-set! ht 'any 'spam))) 666 (error? ; invalid hash-function return value 667 (let ([ht (make-hashtable (lambda (x) 3.5) equal?)]) 668 (hashtable-set! ht 'any 'spam))) 669 (error? ; invalid hash-function return value 670 (let ([ht (make-hashtable (lambda (x) 1+2i) equal?)]) 671 (hashtable-set! ht 'any 'spam))) 672 ; hashtable-update! 673 (error? ; invalid hash-function return value 674 (let ([ht (make-hashtable (lambda (x) "oops") equal?)]) 675 (hashtable-update! ht 'any values 'spam))) 676 #;(error? ; invalid hash-function return value 677 (let ([ht (make-hashtable (lambda (x) -7) equal?)]) 678 (hashtable-update! ht 'any values 'spam))) 679 (error? ; invalid hash-function return value 680 (let ([ht (make-hashtable (lambda (x) 3.5) equal?)]) 681 (hashtable-update! ht 'any values 'spam))) 682 (error? ; invalid hash-function return value 683 (let ([ht (make-hashtable (lambda (x) 1+2i) equal?)]) 684 (hashtable-update! ht 'any values 'spam))) 685 ; hashtable-cell 686 (error? ; invalid hash-function return value 687 (let ([ht (make-hashtable (lambda (x) "oops") equal?)]) 688 (hashtable-cell ht 'any 0))) 689 #;(error? ; invalid hash-function return value 690 (let ([ht (make-hashtable (lambda (x) -7) equal?)]) 691 (hashtable-cell ht 'any 0))) 692 (error? ; invalid hash-function return value 693 (let ([ht (make-hashtable (lambda (x) 3.5) equal?)]) 694 (hashtable-cell ht 'any 0))) 695 (error? ; invalid hash-function return value 696 (let ([ht (make-hashtable (lambda (x) 1+2i) equal?)]) 697 (hashtable-cell ht 'any 0))) 698 ; hashtable-delete! 699 (error? ; invalid hash-function return value 700 (let ([ht (make-hashtable (lambda (x) "oops") equal?)]) 701 (hashtable-delete! ht 'any))) 702 #;(error? ; invalid hash-function return value 703 (let ([ht (make-hashtable (lambda (x) -7) equal?)]) 704 (hashtable-delete! ht 'any))) 705 (error? ; invalid hash-function return value 706 (let ([ht (make-hashtable (lambda (x) 3.5) equal?)]) 707 (hashtable-delete! ht 'any))) 708 (error? ; invalid hash-function return value 709 (let ([ht (make-hashtable (lambda (x) 1+2i) equal?)]) 710 (hashtable-delete! ht 'any))) 711) 712 713(mat eq-hashtable-arguments 714 ; make-weak-eq-hashtable 715 (error? ; wrong argument count 716 (make-weak-eq-hashtable 3 #t)) 717 (error? ; invalid size 718 (make-weak-eq-hashtable -1)) 719 (error? ; invalid size 720 (make-weak-eq-hashtable #t)) 721 (error? ; invalid size 722 (make-weak-eq-hashtable #f)) 723 ; make-weak-eq-hashtable 724 (error? ; wrong argument count 725 (make-ephemeron-eq-hashtable 3 #t)) 726 (error? ; invalid size 727 (make-ephemeron-eq-hashtable -1)) 728 (error? ; invalid size 729 (make-ephemeron-eq-hashtable #t)) 730 (error? ; invalid size 731 (make-ephemeron-eq-hashtable #f)) 732 (begin 733 (define $wht (make-weak-eq-hashtable 50)) 734 (define $eht (make-ephemeron-eq-hashtable 50)) 735 (define $imht (hashtable-copy $wht)) 736 (define $imeht (hashtable-copy $eht)) 737 (define $wht2 (make-weak-eq-hashtable)) 738 (define $eht2 (make-ephemeron-eq-hashtable)) 739 (and (hashtable? $wht) 740 (hashtable? $eht) 741 (eq-hashtable? $wht) 742 (eq-hashtable? $eht) 743 (hashtable-weak? $wht) 744 (not (hashtable-ephemeron? $wht)) 745 (hashtable-ephemeron? $eht) 746 (not (hashtable-weak? $eht)) 747 (eq-hashtable-weak? $wht) 748 (not (eq-hashtable-ephemeron? $wht)) 749 (eq-hashtable-ephemeron? $eht) 750 (not (eq-hashtable-weak? $eht)) 751 (hashtable-mutable? $wht) 752 (hashtable-mutable? $eht) 753 (hashtable? $imht) 754 (hashtable? $imeht) 755 (eq-hashtable? $imht) 756 (eq-hashtable? $imeht) 757 (hashtable-weak? $imht) 758 (not (hashtable-ephemeron? $imht)) 759 (hashtable-ephemeron? $imeht) 760 (not (hashtable-weak? $imeht)) 761 (eq-hashtable-weak? $imht) 762 (not (eq-hashtable-ephemeron? $imht)) 763 (eq-hashtable-ephemeron? $imeht) 764 (not (eq-hashtable-weak? $imeht)) 765 (not (hashtable-mutable? $imht)) 766 (not (hashtable-mutable? $imeht)) 767 (hashtable? $wht2) 768 (hashtable? $eht2) 769 (eq-hashtable? $wht2) 770 (eq-hashtable? $eht2) 771 (hashtable-weak? $wht2) 772 (not (hashtable-ephemeron? $wht2)) 773 (hashtable-ephemeron? $eht2) 774 (not (hashtable-weak? $eht2)) 775 (eq-hashtable-weak? $wht2) 776 (not (eq-hashtable-ephemeron? $ht2)) 777 (eq-hashtable-ephemeron? $eht2) 778 (not (eq-hashtable-weak? $eht2)) 779 (hashtable-mutable? $wht2) 780 (hashtable-mutable? $eht2))) 781 ; eq-hashtable-ref 782 (error? ; wrong argument count 783 (eq-hashtable-ref)) 784 (error? ; wrong argument count 785 (eq-hashtable-ref $wht)) 786 (error? ; wrong argument count 787 (eq-hashtable-ref $wht 'a)) 788 (error? ; wrong argument count 789 (eq-hashtable-ref $wht 'a 'b 'c)) 790 (error? ; not a hashtable 791 (eq-hashtable-ref '(hash . table) 'a 'b)) 792 ; eq-hashtable-contains? 793 (error? ; wrong argument count 794 (eq-hashtable-contains?)) 795 (error? ; wrong argument count 796 (eq-hashtable-contains? $wht)) 797 (error? ; wrong argument count 798 (eq-hashtable-contains? $wht 'a 'b)) 799 (error? ; not a hashtable 800 (eq-hashtable-contains? '(hash . table) 'a)) 801 ; eq-hashtable-set! 802 (error? ; wrong argument count 803 (eq-hashtable-set!)) 804 (error? ; wrong argument count 805 (eq-hashtable-set! $wht)) 806 (error? ; wrong argument count 807 (eq-hashtable-set! $wht 'a)) 808 (error? ; wrong argument count 809 (eq-hashtable-set! $wht 'a 'b 'c)) 810 (error? ; not a hashtable 811 (eq-hashtable-set! '(hash . table) 'a 'b)) 812 (error? ; hashtable not mutable 813 (eq-hashtable-set! $imht 'a 'b)) 814 ; eq-hashtable-update! 815 (error? ; wrong argument count 816 (eq-hashtable-update!)) 817 (error? ; wrong argument count 818 (eq-hashtable-update! $wht)) 819 (error? ; wrong argument count 820 (eq-hashtable-update! $wht 'a values)) 821 (error? ; wrong argument count 822 (eq-hashtable-update! $wht 'a values 'c 'd)) 823 (error? ; not a hashtable 824 (eq-hashtable-update! '(hash . table) 'a values 'b)) 825 (error? ; hashtable not mutable 826 (eq-hashtable-update! $imht 'a values 'b)) 827 (error? ; not a procedure 828 (eq-hashtable-update! $wht 'a "not a procedure" 'b)) 829 ; eq-hashtable-delete! 830 (error? ; wrong argument count 831 (eq-hashtable-delete!)) 832 (error? ; wrong argument count 833 (eq-hashtable-delete! $wht)) 834 (error? ; wrong argument count 835 (eq-hashtable-delete! $wht 'a 'b)) 836 (error? ; not a hashtable 837 (eq-hashtable-delete! '(hash . table) 'a)) 838 (error? ; hashtable not mutable 839 (eq-hashtable-delete! $imht 'a)) 840 ; eq-hashtable-cell 841 (error? ; wrong argument count 842 (eq-hashtable-cell)) 843 (error? ; wrong argument count 844 (eq-hashtable-cell $wht)) 845 (error? ; wrong argument count 846 (eq-hashtable-cell $wht 'a)) 847 (error? ; wrong argument count 848 (eq-hashtable-cell $wht 'a 'b 'c)) 849 (error? ; not a hashtable 850 (eq-hashtable-cell '(hash . table) 'a 'b)) 851 ; eq-hashtable-weak? 852 (error? ; wrong argument count 853 (eq-hashtable-weak?)) 854 (error? ; wrong argument count 855 (eq-hashtable-weak? $ht 3)) 856 (error? ; not a hashtable 857 (eq-hashtable-weak? '(hash . table))) 858 ; eq-hashtable-ephemeron? 859 (error? ; wrong argument count 860 (eq-hashtable-ephemeron?)) 861 (error? ; wrong argument count 862 (eq-hashtable-ephemeron? $ht 3)) 863 (error? ; not a hashtable 864 (eq-hashtable-ephemeron? '(hash . table))) 865) 866 867(mat symbol-hashtable-arguments 868 (begin 869 (define $symht (make-hashtable symbol-hash eq? 50)) 870 (define $imsymht (hashtable-copy $symht)) 871 #t) 872 ; symbol-hashtable-ref 873 (error? ; wrong argument count 874 (symbol-hashtable-ref)) 875 (error? ; wrong argument count 876 (symbol-hashtable-ref $symht)) 877 (error? ; wrong argument count 878 (symbol-hashtable-ref $symht 'a)) 879 (error? ; wrong argument count 880 (symbol-hashtable-ref $symht 'a 'b 'c)) 881 (error? ; not a hashtable 882 (symbol-hashtable-ref '(hash . table) 'a 'b)) 883 (error? ; not a symbol hashtable 884 (symbol-hashtable-ref $ht 'a 'b)) 885 (error? ; not a symbol 886 (symbol-hashtable-ref $symht '(a) 'b)) 887 (error? ; not a symbol 888 (hashtable-ref $symht '(a) 'b)) 889 ; symbol-hashtable-contains? 890 (error? ; wrong argument count 891 (symbol-hashtable-contains?)) 892 (error? ; wrong argument count 893 (symbol-hashtable-contains? $symht)) 894 (error? ; wrong argument count 895 (symbol-hashtable-contains? $symht 'a 'b)) 896 (error? ; not a hashtable 897 (symbol-hashtable-contains? '(hash . table) 'a)) 898 (error? ; not a symbol hashtable 899 (symbol-hashtable-contains? $ht 'a)) 900 (error? ; not a symbol 901 (symbol-hashtable-contains? $symht '(a))) 902 (error? ; not a symbol 903 (hashtable-contains? $symht '(a))) 904 ; symbol-hashtable-set! 905 (error? ; wrong argument count 906 (symbol-hashtable-set!)) 907 (error? ; wrong argument count 908 (symbol-hashtable-set! $symht)) 909 (error? ; wrong argument count 910 (symbol-hashtable-set! $symht 'a)) 911 (error? ; wrong argument count 912 (symbol-hashtable-set! $symht 'a 'b 'c)) 913 (error? ; not a hashtable 914 (symbol-hashtable-set! '(hash . table) 'a 'b)) 915 (error? ; not a symbol hashtable 916 (symbol-hashtable-set! $ht 'a 'b)) 917 (error? ; not a symbol 918 (symbol-hashtable-set! $symht '(a) 'b)) 919 (error? ; not a symbol 920 (hashtable-set! $symht '(a) 'b)) 921 (error? ; hashtable not mutable 922 (symbol-hashtable-set! $imsymht 'a 'b)) 923 ; symbol-hashtable-update! 924 (error? ; wrong argument count 925 (symbol-hashtable-update!)) 926 (error? ; wrong argument count 927 (symbol-hashtable-update! $symht)) 928 (error? ; wrong argument count 929 (symbol-hashtable-update! $symht 'a values)) 930 (error? ; wrong argument count 931 (symbol-hashtable-update! $symht 'a values 'c 'd)) 932 (error? ; not a hashtable 933 (symbol-hashtable-update! '(hash . table) 'a values 'b)) 934 (error? ; not a symbol hashtable 935 (symbol-hashtable-update! $ht 'a values 'b)) 936 (error? ; not a symbol 937 (symbol-hashtable-update! $symht '(a) values 'b)) 938 (error? ; not a symbol 939 (hashtable-update! $symht '(a) values 'b)) 940 (error? ; hashtable not mutable 941 (symbol-hashtable-update! $imsymht 'a values 'b)) 942 (error? ; not a procedure 943 (symbol-hashtable-update! $symht 'a "not a procedure" 'b)) 944 ; symbol-hashtable-delete! 945 (error? ; wrong argument count 946 (symbol-hashtable-delete!)) 947 (error? ; wrong argument count 948 (symbol-hashtable-delete! $symht)) 949 (error? ; wrong argument count 950 (symbol-hashtable-delete! $symht 'a 'b)) 951 (error? ; not a hashtable 952 (symbol-hashtable-delete! '(hash . table) 'a)) 953 (error? ; not a symbol hashtable 954 (symbol-hashtable-delete! $ht 'a)) 955 (error? ; not a symbol 956 (symbol-hashtable-delete! $symht '(a))) 957 (error? ; not a symbol 958 (hashtable-delete! $symht '(a))) 959 (error? ; hashtable not mutable 960 (symbol-hashtable-delete! $imsymht 'a)) 961 ; symbol-hashtable-cell 962 (error? ; wrong argument count 963 (symbol-hashtable-cell)) 964 (error? ; wrong argument count 965 (symbol-hashtable-cell $symht)) 966 (error? ; wrong argument count 967 (symbol-hashtable-cell $symht 'a)) 968 (error? ; wrong argument count 969 (symbol-hashtable-cell $symht 'a 'b 'c)) 970 (error? ; not a hashtable 971 (symbol-hashtable-cell '(hash . table) 'a 'b)) 972 (error? ; not a symbol hashtable 973 (symbol-hashtable-cell $ht 'a 'b)) 974 (error? ; not a symbol 975 (symbol-hashtable-cell $symht '(a) 'b)) 976 (error? ; not a symbol 977 (hashtable-cell $symht '(a) 'b)) 978) 979 980(mat eqv-hashtable-arguments 981 ; make-weak-eqv-hashtable 982 (error? ; wrong argument count 983 (make-weak-eqv-hashtable 3 #t)) 984 (error? ; invalid size 985 (make-weak-eqv-hashtable -1)) 986 (error? ; invalid size 987 (make-weak-eqv-hashtable #t)) 988 (error? ; invalid size 989 (make-weak-eqv-hashtable #f)) 990 ; make-ephemeron-eqv-hashtable 991 (error? ; wrong argument count 992 (make-ephemeron-eqv-hashtable 3 #t)) 993 (error? ; invalid size 994 (make-ephemeron-eqv-hashtable -1)) 995 (error? ; invalid size 996 (make-ephemeron-eqv-hashtable #t)) 997 (error? ; invalid size 998 (make-ephemeron-eqv-hashtable #f)) 999) 1000 1001(mat nonweak-eq-hashtable 1002 (begin 1003 (define h (make-eq-hashtable 32)) 1004 (and (hashtable? h) 1005 (eq-hashtable? h) 1006 (hashtable-mutable? h) 1007 (not (eq-hashtable-weak? h)) 1008 (not (eq-hashtable-ephemeron? h)) 1009 (not (hashtable-weak? h)) 1010 (not (hashtable-ephemeron? h)))) 1011 (eq? (hashtable-hash-function h) #f) 1012 (eq? (hashtable-equivalence-function h) eq?) 1013 (equal? (hashtable-size h) 0) 1014 (equal-entries? h '#() '#()) 1015 (eqv? (hashtable-set! h 'a 'aval) (void)) 1016 (equal? 1017 (list 1018 (hashtable-contains? h 'a) 1019 (hashtable-contains? h 'b) 1020 (hashtable-contains? h 'c)) 1021 '(#t #f #f)) 1022 (eqv? (hashtable-set! h 'b 'bval) (void)) 1023 (equal? 1024 (list 1025 (hashtable-contains? h 'a) 1026 (hashtable-contains? h 'b) 1027 (hashtable-contains? h 'c)) 1028 '(#t #t #f)) 1029 (eqv? (hashtable-set! h 'c 'cval) (void)) 1030 (equal? 1031 (list 1032 (hashtable-contains? h 'a) 1033 (hashtable-contains? h 'b) 1034 (hashtable-contains? h 'c)) 1035 '(#t #t #t)) 1036 (equal? (hashtable-size h) 3) 1037 (equal-entries? h '#(b c a) '#(bval cval aval)) 1038 #;(same-elements? (list->vector (hashtable-map h cons)) '#((a . aval) (b . bval) (c . cval))) 1039 #;(same-elements? 1040 (let ([v (make-vector 3)] [i 0]) 1041 (hashtable-for-each h (lambda (key val) (vector-set! v i (cons key val)) (set! i (fx+ i 1)))) 1042 v) 1043 '#((a . aval) (b . bval) (c . cval))) 1044 #;(same-elements? 1045 (let ([v (make-vector 3)] [i 0]) 1046 (hashtable-for-each-cell h (lambda (a) (vector-set! v i a) (set! i (fx+ i 1)))) 1047 v) 1048 '#((a . aval) (b . bval) (c . cval))) 1049 (equal? (hashtable-ref h 'a 1) 'aval) 1050 (equal? (hashtable-ref h 'b #f) 'bval) 1051 (equal? (hashtable-ref h 'c 'nope) 'cval) 1052 (eqv? (hashtable-delete! h 'b) (void)) 1053 (equal? (hashtable-size h) 2) 1054 (equal-entries? h '#(a c) '#(aval cval)) 1055 (begin 1056 (define h2 (hashtable-copy h #t)) 1057 (and (hashtable? h2) 1058 (eq-hashtable? h2) 1059 (hashtable-mutable? h2) 1060 (not (hashtable-weak? h2)) 1061 (not (eq-hashtable-weak? h2)) 1062 (not (hashtable-ephemeron? h2)) 1063 (not (eq-hashtable-ephemeron? h2)))) 1064 (eq? (hashtable-hash-function h2) #f) 1065 (eq? (hashtable-equivalence-function h2) eq?) 1066 (equal? (hashtable-size h2) 2) 1067 (equal-entries? h2 '#(a c) '#(aval cval)) 1068 (eqv? (hashtable-clear! h 4) (void)) 1069 (equal? 1070 (list 1071 (hashtable-size h) 1072 (hashtable-ref h 'a 1) 1073 (hashtable-ref h 'b #f) 1074 (hashtable-ref h 'c 'nope)) 1075 '(0 1 #f nope)) 1076 (equal-entries? h '#() '#()) 1077 (equal? 1078 (list 1079 (hashtable-size h2) 1080 (hashtable-ref h2 'a 1) 1081 (hashtable-ref h2 'b #f) 1082 (hashtable-ref h2 'c 'nope)) 1083 '(2 aval #f cval)) 1084 (equal-entries? h2 '#(a c) '#(aval cval)) 1085 (eqv? 1086 (hashtable-update! h 'q 1087 (lambda (x) (+ x 1)) 1088 17) 1089 (void)) 1090 (equal? (hashtable-ref h 'q #f) 18) 1091 (eqv? 1092 (hashtable-update! h 'q 1093 (lambda (x) (+ x 1)) 1094 17) 1095 (void)) 1096 (equal? (hashtable-ref h 'q #f) 19) 1097 (equal? (hashtable-size h) 1) 1098 ; test hashtable-copy when some keys may have moved 1099 (let ([t (parameterize ([collect-request-handler void]) 1100 (let ([h4a (make-eq-hashtable 32)] 1101 [k* (map list (make-list 100))]) 1102 (for-each (lambda (x) (hashtable-set! h4a x x)) k*) 1103 (collect) 1104 ; create copy after collection but before otherwise touching h4a 1105 (let ([h4b (hashtable-copy h4a #t)]) 1106 (andmap 1107 (lambda (k) (eq? (hashtable-ref h4b k #f) k)) 1108 k*))))]) 1109 (collect) 1110 t) 1111 1112 ; test for proper shrinkage 1113 (eqv? 1114 (let ([ht (make-eq-hashtable 32)]) 1115 (for-each 1116 (lambda (k*) (for-each (lambda (k) (hashtable-delete! ht k)) k*)) 1117 (let ([k** (map (lambda (x) (map list (make-list 1000))) 1118 (make-list 100))]) 1119 (for-each 1120 (lambda (k*) (map (lambda (k) (hashtable-set! ht k 75)) k*)) 1121 k**) 1122 k**)) 1123 (#%$hashtable-veclen ht)) 1124 32) 1125) 1126 1127(mat weak-eq-hashtable 1128 (begin 1129 (define ka (list 'a)) 1130 (define kb (list 'b)) 1131 (define kc (list 'c)) 1132 (define kq (list 'q)) 1133 (define ky (list 'y)) 1134 (define kz (list 'z)) 1135 #t) 1136 (begin 1137 (define h (make-weak-eq-hashtable 32)) 1138 (and (hashtable? h) 1139 (eq-hashtable? h) 1140 (hashtable-mutable? h) 1141 (hashtable-weak? h) 1142 (eq-hashtable-weak? h))) 1143 (eq? (hashtable-hash-function h) #f) 1144 (eq? (hashtable-equivalence-function h) eq?) 1145 (equal? (hashtable-size h) 0) 1146 (equal-entries? h '#() '#()) 1147 (eqv? (hashtable-set! h ka 'aval) (void)) 1148 (equal? 1149 (list 1150 (hashtable-contains? h ka) 1151 (hashtable-contains? h kb) 1152 (hashtable-contains? h kc)) 1153 '(#t #f #f)) 1154 (eqv? (hashtable-set! h kb 'bval) (void)) 1155 (equal? 1156 (list 1157 (hashtable-contains? h ka) 1158 (hashtable-contains? h kb) 1159 (hashtable-contains? h kc)) 1160 '(#t #t #f)) 1161 (eqv? (hashtable-set! h kc 'cval) (void)) 1162 (equal? 1163 (list 1164 (hashtable-contains? h ka) 1165 (hashtable-contains? h kb) 1166 (hashtable-contains? h kc)) 1167 '(#t #t #t)) 1168 (equal? (hashtable-size h) 3) 1169 (equal-entries? h '#((a) (b) (c)) '#(aval bval cval)) 1170 (andmap weak-pair? (vector->list (hashtable-cells h))) 1171 #;(same-elements? (list->vector (hashtable-map h cons)) '#(((a) . aval) ((b) . bval) ((c) . cval))) 1172 #;(same-elements? 1173 (let ([v (make-vector 3)] [i 0]) 1174 (hashtable-for-each h (lambda (key val) (vector-set! v i (cons key val)) (set! i (fx+ i 1)))) 1175 v) 1176 '#(((a) . aval) ((b) . bval) ((c) . cval))) 1177 #;(same-elements? 1178 (let ([v (make-vector 3)] [i 0]) 1179 (hashtable-for-each-cell h (lambda (a) (vector-set! v i a) (set! i (fx+ i 1)))) 1180 v) 1181 '#(((a) . aval) ((b) . bval) ((c) . cval))) 1182 (equal? (hashtable-ref h ka 1) 'aval) 1183 (equal? (hashtable-ref h kb #f) 'bval) 1184 (equal? (hashtable-ref h kc 'nope) 'cval) 1185 (eqv? (hashtable-delete! h kb) (void)) 1186 (equal? (hashtable-size h) 2) 1187 (equal-entries? h '#((a) (c)) '#(aval cval)) 1188 (begin 1189 (define h2 (hashtable-copy h #t)) 1190 (and (hashtable? h2) 1191 (eq-hashtable? h2) 1192 (hashtable-mutable? h2) 1193 (eq-hashtable-weak? h2) 1194 (hashtable-weak? h2))) 1195 (eq? (hashtable-hash-function h2) #f) 1196 (eq? (hashtable-equivalence-function h2) eq?) 1197 (equal? (hashtable-size h2) 2) 1198 (equal-entries? h2 '#((a) (c)) '#(aval cval)) 1199 (eqv? (hashtable-clear! h 4) (void)) 1200 (equal? 1201 (list 1202 (hashtable-size h) 1203 (hashtable-ref h ka 1) 1204 (hashtable-ref h kb #f) 1205 (hashtable-ref h kc 'nope)) 1206 '(0 1 #f nope)) 1207 (equal-entries? h '#() '#()) 1208 (equal? 1209 (list 1210 (hashtable-size h2) 1211 (hashtable-ref h2 ka 1) 1212 (hashtable-ref h2 kb #f) 1213 (hashtable-ref h2 kc 'nope)) 1214 '(2 aval #f cval)) 1215 (equal-entries? h2 '#((a) (c)) '#(aval cval)) 1216 (eqv? 1217 (hashtable-update! h kq 1218 (lambda (x) (+ x 1)) 1219 17) 1220 (void)) 1221 (equal? (hashtable-ref h kq #f) 18) 1222 (eqv? 1223 (hashtable-update! h kq 1224 (lambda (x) (+ x 1)) 1225 17) 1226 (void)) 1227 (equal? (hashtable-ref h kq #f) 19) 1228 (equal? (hashtable-size h) 1) 1229 (equal-entries? h '#((q)) '#(19)) 1230 (eqv? 1231 (begin 1232 (set! kq (void)) 1233 (collect (collect-maximum-generation)) 1234 (hashtable-size h)) 1235 0) 1236 (equal-entries? h '#() '#()) 1237 #;(eqv? (hashtable-map h (lambda args (error #f "oops"))) '()) 1238 #;(eqv? (hashtable-for-each h (lambda args (error #f "oops"))) (void)) 1239 #;(eqv? (hashtable-for-each-cell h (lambda args (error #f "oops"))) (void)) 1240 (equal? (hashtable-ref h ky #f) #f) 1241 (eqv? 1242 (hashtable-set! h ky 'toad) 1243 (void)) 1244 (equal? (hashtable-ref h ky #f) 'toad) 1245 (equal? (hashtable-ref h kz #f) #f) 1246 (eqv? 1247 (hashtable-update! h kz list 'frog) 1248 (void)) 1249 (equal? (hashtable-ref h kz #f) '(frog)) 1250 (equal-entries? 1251 h 1252 (vector kz ky) 1253 (vector (hashtable-ref h kz #f) 'toad)) 1254 (eqv? (hashtable-ref h '(zippo) 'nil) 'nil) 1255 (begin 1256 (define h3 (hashtable-copy h2 #f)) 1257 (and (hashtable? h3) 1258 (eq-hashtable? h3) 1259 (not (hashtable-mutable? h3)) 1260 (eq-hashtable-weak? h3) 1261 (hashtable-weak? h3))) 1262 (equal-entries? h2 '#((a) (c)) '#(aval cval)) 1263 (equal-entries? h3 '#((a) (c)) '#(aval cval)) 1264 (equal? 1265 (begin 1266 (set! ka (void)) 1267 (collect (collect-maximum-generation)) 1268 (list (hashtable-size h2) (hashtable-size h3))) 1269 '(1 1)) 1270 (equal-entries? h2 '#((c)) '#(cval)) 1271 (equal-entries? h3 '#((c)) '#(cval)) 1272 (eqv? 1273 (begin 1274 (set! h3 (void)) 1275 (collect (collect-maximum-generation)) 1276 (hashtable-size h2)) 1277 1) 1278 (equal-entries? h2 '#((c)) '#(cval)) 1279 1280 ; test for proper shrinkage 1281 (eqv? 1282 (let ([ht (make-eq-hashtable 32)]) 1283 (for-each 1284 (lambda (k*) (for-each (lambda (k) (hashtable-delete! ht k)) k*)) 1285 (let ([k** (map (lambda (x) (map list (make-list 1000))) 1286 (make-list 100))]) 1287 (for-each 1288 (lambda (k*) (map (lambda (k) (hashtable-set! ht k 75)) k*)) 1289 k**) 1290 k**)) 1291 (#%$hashtable-veclen ht)) 1292 32) 1293 1294 ; test for proper shrinkage as objects are bwp'd 1295 ; uses delete to trigger final shrinkage 1296 (equal? 1297 (let* ([ht (make-weak-eq-hashtable 32)] 1298 [len (#%$hashtable-veclen ht)]) 1299 (hashtable-set! ht 'a 'b) 1300 (for-each 1301 (lambda (k*) (map (lambda (k) (hashtable-set! ht k 75)) k*)) 1302 (map (lambda (x) (map list (make-list 1000))) (make-list 100))) 1303 (collect (collect-maximum-generation)) 1304 (hashtable-delete! ht 'a) 1305 (list (hashtable-size ht) (= (#%$hashtable-veclen ht) len))) 1306 '(0 #t)) 1307 1308 ; test that weak-hashtable values *do* make keys reachable 1309 (let ([wk1 (list 1)] 1310 [wk2 (list 2)] 1311 [wk3 (list 3)] 1312 [wk4 (list 4)] 1313 [ht (make-weak-eq-hashtable)]) 1314 (hashtable-set! ht wk1 wk1) 1315 (hashtable-set! ht wk2 wk1) 1316 (hashtable-set! ht wk3 wk3) 1317 (hashtable-set! ht wk4 wk2) 1318 (collect (collect-maximum-generation)) 1319 (and 1320 (equal-entries? ht '#((1) (2) (3) (4)) '#((1) (1) (3) (2))) 1321 (equal? (hashtable-ref ht wk1 #f) wk1) 1322 (equal? (hashtable-ref ht wk2 #f) wk1) 1323 (equal? (hashtable-ref ht wk3 #f) wk3) 1324 (equal? (hashtable-ref ht wk4 #f) wk2) 1325 (begin 1326 (set! wk1 #f) 1327 (set! wk2 #f) 1328 (set! wk3 #f) 1329 (collect (collect-maximum-generation)) 1330 (and 1331 (equal-entries? ht '#((1) (2) (3) (4)) '#((1) (1) (3) (2))) 1332 (equal? (hashtable-ref ht wk4 #f) '(2)) 1333 (begin 1334 (set! wk4 #f) 1335 (collect (collect-maximum-generation)) 1336 (equal-entries? ht '#((1) (2) (3)) '#((1) (1) (3)))))))) 1337) 1338 1339(mat ephemeron-eq-hashtable 1340 (begin 1341 (define ka (list 'a)) ; will map to self \ Doesn't do anything to check 1342 (define kb (list 'b)) ; will map to kc \ | ephemeronness, but just in 1343 (define kc (list 'c)) ; will map to kb / / case. 1344 (define kq (list 'q)) 1345 (define ky (list 'y)) 1346 (define kz (list 'z)) 1347 #t) 1348 (begin 1349 (define h (make-ephemeron-eq-hashtable 32)) 1350 (and (hashtable? h) 1351 (eq-hashtable? h) 1352 (hashtable-mutable? h) 1353 (hashtable-ephemeron? h) 1354 (eq-hashtable-ephemeron? h))) 1355 (eq? (hashtable-hash-function h) #f) 1356 (eq? (hashtable-equivalence-function h) eq?) 1357 (equal? (hashtable-size h) 0) 1358 (equal-entries? h '#() '#()) 1359 (eqv? (hashtable-set! h ka ka) (void)) 1360 (equal? 1361 (list 1362 (hashtable-contains? h ka) 1363 (hashtable-contains? h kb) 1364 (hashtable-contains? h kc)) 1365 '(#t #f #f)) 1366 (eqv? (hashtable-set! h kb kc) (void)) 1367 (equal? 1368 (list 1369 (hashtable-contains? h ka) 1370 (hashtable-contains? h kb) 1371 (hashtable-contains? h kc)) 1372 '(#t #t #f)) 1373 (eqv? (hashtable-set! h kc kb) (void)) 1374 (equal? 1375 (list 1376 (hashtable-contains? h ka) 1377 (hashtable-contains? h kb) 1378 (hashtable-contains? h kc)) 1379 '(#t #t #t)) 1380 (equal? (hashtable-size h) 3) 1381 (equal-entries? h '#((a) (b) (c)) '#((a) (c) (b))) 1382 (andmap ephemeron-pair? (vector->list (hashtable-cells h))) 1383 #;(same-elements? (list->vector (hashtable-map h cons)) '#(((a) . a) ((b) . c) ((c) . b))) 1384 #;(same-elements? 1385 (let ([v (make-vector 3)] [i 0]) 1386 (hashtable-for-each h (lambda (key val) (vector-set! v i (cons key val)) (set! i (fx+ i 1)))) 1387 v) 1388 '#(((a) . a) ((b) . c) ((c) . b))) 1389 #;(same-elements? 1390 (let ([v (make-vector 3)] [i 0]) 1391 (hashtable-for-each-cell h (lambda (a) (vector-set! v i a) (set! i (fx+ i 1)))) 1392 v) 1393 '#(((a) . a) ((b) . c) ((c) . b))) 1394 (equal? (hashtable-ref h ka 1) '(a)) 1395 (equal? (hashtable-ref h kb #f) '(c)) 1396 (equal? (hashtable-ref h kc 'nope) '(b)) 1397 (eqv? (hashtable-delete! h kb) (void)) 1398 (equal? (hashtable-size h) 2) 1399 (equal-entries? h '#((a) (c)) '#((a) (b))) 1400 (begin 1401 (define h2 (hashtable-copy h #t)) 1402 (and (hashtable? h2) 1403 (eq-hashtable? h2) 1404 (hashtable-mutable? h2) 1405 (eq-hashtable-ephemeron? h2) 1406 (hashtable-ephemeron? h2))) 1407 (eq? (hashtable-hash-function h2) #f) 1408 (eq? (hashtable-equivalence-function h2) eq?) 1409 (equal? (hashtable-size h2) 2) 1410 (equal-entries? h2 '#((a) (c)) '#((a) (b))) 1411 (eqv? (hashtable-clear! h 4) (void)) 1412 (equal? 1413 (list 1414 (hashtable-size h) 1415 (hashtable-ref h ka 1) 1416 (hashtable-ref h kb #f) 1417 (hashtable-ref h kc 'nope)) 1418 '(0 1 #f nope)) 1419 (equal-entries? h '#() '#()) 1420 (equal? 1421 (list 1422 (hashtable-size h2) 1423 (hashtable-ref h2 ka 1) 1424 (hashtable-ref h2 kb #f) 1425 (hashtable-ref h2 kc 'nope)) 1426 '(2 (a) #f (b))) 1427 (equal-entries? h2 '#((a) (c)) '#((a) (b))) 1428 (eqv? 1429 (hashtable-update! h kq 1430 (lambda (x) (+ x 1)) 1431 17) 1432 (void)) 1433 (equal? (hashtable-ref h kq #f) 18) 1434 (eqv? 1435 (hashtable-update! h kq 1436 (lambda (x) (+ x 1)) 1437 17) 1438 (void)) 1439 (equal? (hashtable-ref h kq #f) 19) 1440 (equal? (hashtable-size h) 1) 1441 (equal-entries? h '#((q)) '#(19)) 1442 (eqv? 1443 (begin 1444 (set! kq (void)) 1445 (collect (collect-maximum-generation)) 1446 (hashtable-size h)) 1447 0) 1448 (equal-entries? h '#() '#()) 1449 #;(eqv? (hashtable-map h (lambda args (error #f "oops"))) '()) 1450 #;(eqv? (hashtable-for-each h (lambda args (error #f "oops"))) (void)) 1451 #;(eqv? (hashtable-for-each-cell h (lambda args (error #f "oops"))) (void)) 1452 (equal? (hashtable-ref h ky #f) #f) 1453 (eqv? 1454 (hashtable-set! h ky 'toad) 1455 (void)) 1456 (equal? (hashtable-ref h ky #f) 'toad) 1457 (equal? (hashtable-ref h kz #f) #f) 1458 (eqv? 1459 (hashtable-update! h kz list 'frog) 1460 (void)) 1461 (equal? (hashtable-ref h kz #f) '(frog)) 1462 (equal-entries? 1463 h 1464 (vector kz ky) 1465 (vector (hashtable-ref h kz #f) 'toad)) 1466 (eqv? (hashtable-ref h '(zippo) 'nil) 'nil) 1467 (begin 1468 (define h3 (hashtable-copy h2 #f)) 1469 (and (hashtable? h3) 1470 (eq-hashtable? h3) 1471 (not (hashtable-mutable? h3)) 1472 (eq-hashtable-ephemeron? h3) 1473 (hashtable-ephemeron? h3))) 1474 (equal-entries? h2 '#((a) (c)) '#((a) (b))) 1475 (equal-entries? h3 '#((a) (c)) '#((a) (b))) 1476 (equal? 1477 (begin 1478 (set! ka (void)) 1479 (collect (collect-maximum-generation)) 1480 (list (hashtable-size h2) (hashtable-size h3))) 1481 '(1 1)) 1482 (equal-entries? h2 '#((c)) '#((b))) 1483 (equal-entries? h3 '#((c)) '#((b))) 1484 (eqv? 1485 (begin 1486 (set! h3 (void)) 1487 (collect (collect-maximum-generation)) 1488 (hashtable-size h2)) 1489 1) 1490 (equal-entries? h2 '#((c)) '#((b))) 1491 1492 ; test for proper shrinkage 1493 (eqv? 1494 (let ([ht (make-eq-hashtable 32)]) 1495 (for-each 1496 (lambda (k*) (for-each (lambda (k) (hashtable-delete! ht k)) k*)) 1497 (let ([k** (map (lambda (x) (map list (make-list 1000))) 1498 (make-list 100))]) 1499 (for-each 1500 (lambda (k*) (map (lambda (k) (hashtable-set! ht k 75)) k*)) 1501 k**) 1502 k**)) 1503 (#%$hashtable-veclen ht)) 1504 32) 1505 1506 ; test for proper shrinkage as objects are bwp'd 1507 ; uses delete to trigger final shrinkage 1508 (equal? 1509 (let* ([ht (make-ephemeron-eq-hashtable 32)] 1510 [len (#%$hashtable-veclen ht)]) 1511 (hashtable-set! ht 'a 'b) 1512 (for-each 1513 (lambda (k*) (map (lambda (k) (hashtable-set! ht k 75)) k*)) 1514 (map (lambda (x) (map list (make-list 1000))) (make-list 100))) 1515 (collect (collect-maximum-generation)) 1516 (hashtable-delete! ht 'a) 1517 (list (hashtable-size ht) (= (#%$hashtable-veclen ht) len))) 1518 '(0 #t)) 1519 1520 ; test that ephemeron-hashtable values don't make keys reachable 1521 (let ([wk1 (list 1)] 1522 [wk2 (list 2)] 1523 [wk3 (list 3)] 1524 [wk4 (list 4)] 1525 [ht (make-ephemeron-eq-hashtable)]) 1526 (hashtable-set! ht wk1 wk1) 1527 (hashtable-set! ht wk2 wk1) 1528 (hashtable-set! ht wk3 wk3) 1529 (hashtable-set! ht wk4 wk2) 1530 (collect (collect-maximum-generation)) 1531 (and 1532 (equal-entries? ht '#((1) (2) (3) (4)) '#((1) (1) (3) (2))) 1533 (equal? (hashtable-ref ht wk1 #f) wk1) 1534 (equal? (hashtable-ref ht wk2 #f) wk1) 1535 (equal? (hashtable-ref ht wk3 #f) wk3) 1536 (equal? (hashtable-ref ht wk4 #f) wk2) 1537 (begin 1538 (set! wk1 #f) 1539 (set! wk2 #f) 1540 (set! wk3 #f) 1541 (collect (collect-maximum-generation)) 1542 (and 1543 (equal-entries? ht '#((1) (2) (4)) '#((1) (1) (2))) 1544 (equal? (hashtable-ref ht wk4 #f) '(2)) 1545 (begin 1546 (set! wk4 #f) 1547 (collect (collect-maximum-generation)) 1548 (equal-entries? ht '#() '#())))))) 1549) 1550 1551(mat eq-hashtable-cell 1552 (let () 1553 (define-record fribble (x)) 1554 (define random-object 1555 (lambda (x) 1556 (case (random 9) 1557 [(0) (cons 'a 'b)] 1558 [(1) (vector 'c)] 1559 [(2) (string #\a #\b)] 1560 [(3) (make-fribble 'q)] 1561 [(4) (gensym)] 1562 [(5) (open-output-string)] 1563 [(6) (fxvector 15 55)] 1564 [(7) (lambda () x)] 1565 [else (box 'top)]))) 1566 (let ([ls1 (let f ([n 10000]) 1567 (if (fx= n 0) 1568 '() 1569 (cons 1570 (cons (random-object 4) (random-object 7)) 1571 (f (fx- n 1)))))] 1572 [ht (make-eq-hashtable)] 1573 [wht (make-weak-eq-hashtable)] 1574 [eht (make-ephemeron-eq-hashtable)]) 1575 (let ([ls2 (map (lambda (a1) (eq-hashtable-cell ht (car a1) (cdr a1))) ls1)] 1576 [ls3 (map (lambda (a1) (hashtable-cell wht (car a1) (cdr a1))) ls1)] 1577 [ls4 (map (lambda (a1) (hashtable-cell eht (car a1) (cdr a1))) ls1)]) 1578 (unless (andmap (lambda (a1 a2 a3 a4) 1579 (and (eq? (car a1) (car a2)) 1580 (eq? (car a2) (car a3)) 1581 (eq? (car a2) (car a4)))) 1582 ls1 ls2 ls3 ls4) 1583 (errorf #f "keys are not eq")) 1584 (unless (andmap (lambda (a1 a2 a3 a4) 1585 (and (eq? (cdr a1) (cdr a2)) 1586 (eq? (cdr a2) (cdr a3)) 1587 (eq? (cdr a2) (cdr a4)))) 1588 ls1 ls2 ls3 ls4) 1589 (errorf #f "values are not eq")) 1590 (for-each (lambda (a1) 1591 (let ([o (random-object 3)]) 1592 ;; Value refers to key: 1593 (hashtable-set! eht o (list o (car a1))))) 1594 ls1) 1595 (for-each 1596 (lambda (a1) 1597 (when (fx< (random 10) 5) 1598 (set-car! a1 #f))) 1599 ls1) 1600 (let loop ([i (min (expt (collect-generation-radix) (collect-maximum-generation)) 1000)]) 1601 (unless (fx= i 0) 1602 (collect) 1603 (unless (andmap (lambda (a2 a3 a4) (and (eq? (car a2) (car a3)) (eq? (car a2) (car a4)))) 1604 ls2 ls3 ls4) 1605 (errorf #f "a2/a3/a4 keys not eq after collection")) 1606 (unless (and (andmap (lambda (a3) (not (bwp-object? (car a3)))) ls3) 1607 (andmap (lambda (a4) (not (bwp-object? (car a4)))) ls4)) 1608 (errorf #f "keys have been bwp'd")) 1609 (loop (fx- i 1)))) 1610 (for-each 1611 (lambda (a2) 1612 (hashtable-delete! ht (car a2)) 1613 (set-car! a2 #f)) 1614 ls2) 1615 (unless (and (equal? (hashtable-keys ht) '#()) 1616 (equal? (hashtable-values ht) '#()) 1617 (zero? (hashtable-size ht))) 1618 (errorf #f "ht has not been cleared out")) 1619 (let loop ([i (min (expt (collect-generation-radix) (collect-maximum-generation)) 1000)]) 1620 (unless (fx= i 0) 1621 (collect) 1622 (unless (andmap (lambda (a1 a3 a4) 1623 (or (not (car a1)) 1624 (and (eq? (car a1) (car a3)) 1625 (eq? (car a1) (car a4))))) 1626 ls1 ls3 ls4) 1627 (errorf #f "a1/a3/a4 keys not eq after collection")) 1628 (loop (fx- i 1)))) 1629 (for-each 1630 (lambda (a1 a3 a4) 1631 (unless (or (car a1) 1632 (and (bwp-object? (car a3)) 1633 (bwp-object? (car a4)))) 1634 (errorf #f "~s has not been bwp'd I" (car a3)))) 1635 ls1 ls3 ls4) 1636 (for-each (lambda (a1) (set-car! a1 #f)) ls1) 1637 (collect (collect-maximum-generation)) 1638 (unless (and (andmap (lambda (a3) (bwp-object? (car a3))) ls3) 1639 (andmap (lambda (a4) (bwp-object? (car a4))) ls4)) 1640 (errorf #f "keys have not been bwp'd II")) 1641 (unless (and (equal? (hashtable-keys wht) '#()) 1642 (equal? (hashtable-values wht) '#()) 1643 (zero? (hashtable-size wht))) 1644 (errorf #f "wht has not been cleared out")) 1645 (unless (and (equal? (hashtable-keys eht) '#()) 1646 (equal? (hashtable-values eht) '#()) 1647 (zero? (hashtable-size eht))) 1648 (errorf #f "eht has not been cleared out")))) 1649 #t) 1650) 1651 1652(mat $nonweak-eq-hashtable 1653 (begin 1654 (define h (make-eq-hashtable 32)) 1655 (and (hashtable? h) 1656 (eq-hashtable? h) 1657 (hashtable-mutable? h) 1658 (not (eq-hashtable-weak? h)) 1659 (not (hashtable-weak? h)) 1660 (not (eq-hashtable-ephemeron? h)) 1661 (not (hashtable-ephemeron? h)))) 1662 (eq? (hashtable-hash-function h) #f) 1663 (eq? (hashtable-equivalence-function h) eq?) 1664 (equal? (hashtable-size h) 0) 1665 (equal-entries? h '#() '#()) 1666 (eqv? (eq-hashtable-set! h 'a 'aval) (void)) 1667 (equal? 1668 (list 1669 (eq-hashtable-contains? h 'a) 1670 (eq-hashtable-contains? h 'b) 1671 (eq-hashtable-contains? h 'c)) 1672 '(#t #f #f)) 1673 (eqv? (eq-hashtable-set! h 'b 'bval) (void)) 1674 (equal? 1675 (list 1676 (eq-hashtable-contains? h 'a) 1677 (eq-hashtable-contains? h 'b) 1678 (eq-hashtable-contains? h 'c)) 1679 '(#t #t #f)) 1680 (eqv? (eq-hashtable-set! h 'c 'cval) (void)) 1681 (equal? 1682 (list 1683 (eq-hashtable-contains? h 'a) 1684 (eq-hashtable-contains? h 'b) 1685 (eq-hashtable-contains? h 'c)) 1686 '(#t #t #t)) 1687 (equal? (hashtable-size h) 3) 1688 (equal-entries? h '#(b c a) '#(bval cval aval)) 1689 (equal? (eq-hashtable-ref h 'a 1) 'aval) 1690 (equal? (eq-hashtable-ref h 'b #f) 'bval) 1691 (equal? (eq-hashtable-ref h 'c 'nope) 'cval) 1692 (eqv? (eq-hashtable-delete! h 'b) (void)) 1693 (equal? (hashtable-size h) 2) 1694 (equal-entries? h '#(a c) '#(aval cval)) 1695 (begin 1696 (define h2 (hashtable-copy h #t)) 1697 (and (hashtable? h2) 1698 (eq-hashtable? h2) 1699 (hashtable-mutable? h2) 1700 (not (eq-hashtable-weak? h2)) 1701 (not (hashtable-weak? h2)))) 1702 (equal? (hashtable-size h2) 2) 1703 (equal-entries? h2 '#(a c) '#(aval cval)) 1704 (eqv? (hashtable-clear! h 4) (void)) 1705 (equal? 1706 (list 1707 (hashtable-size h) 1708 (eq-hashtable-ref h 'a 1) 1709 (eq-hashtable-ref h 'b #f) 1710 (eq-hashtable-ref h 'c 'nope)) 1711 '(0 1 #f nope)) 1712 (equal-entries? h '#() '#()) 1713 (equal? 1714 (list 1715 (hashtable-size h2) 1716 (eq-hashtable-ref h2 'a 1) 1717 (eq-hashtable-ref h2 'b #f) 1718 (eq-hashtable-ref h2 'c 'nope)) 1719 '(2 aval #f cval)) 1720 (equal-entries? h2 '#(a c) '#(aval cval)) 1721 (eqv? 1722 (eq-hashtable-update! h 'q 1723 (lambda (x) (+ x 1)) 1724 17) 1725 (void)) 1726 (equal? (eq-hashtable-ref h 'q #f) 18) 1727 (eqv? 1728 (eq-hashtable-update! h 'q 1729 (lambda (x) (+ x 1)) 1730 17) 1731 (void)) 1732 (equal? (eq-hashtable-ref h 'q #f) 19) 1733 (equal? (hashtable-size h) 1) 1734 ; test hashtable-copy when some keys may have moved 1735 (let ([t (parameterize ([collect-request-handler void]) 1736 (let ([h4a (make-eq-hashtable 32)] 1737 [k* (map list (make-list 100))]) 1738 (for-each (lambda (x) (eq-hashtable-set! h4a x x)) k*) 1739 (collect) 1740 ; create copy after collection but before otherwise touching h4a 1741 (let ([h4b (hashtable-copy h4a #t)]) 1742 (andmap 1743 (lambda (k) (eq? (eq-hashtable-ref h4b k #f) k)) 1744 k*))))]) 1745 (collect) 1746 t) 1747 1748 ; test for proper shrinkage, etc. 1749 (equal? 1750 (let* ([ht (make-eq-hashtable)] [minlen (#%$hashtable-veclen ht)]) 1751 (define power-of-two? (lambda (n) (fx= (fxbit-count n) 1))) 1752 (let f ([i 0]) 1753 (unless (fx= i (expt 2 17)) 1754 (let ([k (fx* i 2)]) 1755 (eq-hashtable-set! ht k i) 1756 (f (fx+ i 1)) 1757 (assert (eq-hashtable-contains? ht k)) 1758 (assert (power-of-two? (#%$hashtable-veclen ht))) 1759 (eq-hashtable-delete! ht k)))) 1760 (list (hashtable-size ht) (fx= (#%$hashtable-veclen ht) minlen))) 1761 '(0 #t)) 1762 1763 (equal? 1764 (let ([ht (make-eq-hashtable 32)]) 1765 (define power-of-two? (lambda (n) (fx= (fxbit-count n) 1))) 1766 (let f ([i 0]) 1767 (unless (fx= i (expt 2 17)) 1768 (let ([k (fx* i 2)]) 1769 (eq-hashtable-set! ht k i) 1770 (f (fx+ i 1)) 1771 (assert (eq-hashtable-contains? ht k)) 1772 (assert (power-of-two? (#%$hashtable-veclen ht))) 1773 (eq-hashtable-delete! ht k)))) 1774 (list (hashtable-size ht) (#%$hashtable-veclen ht))) 1775 '(0 32)) 1776) 1777 1778(mat $weak-eq-hashtable 1779 (begin 1780 (define ka (list 'a)) 1781 (define kb (list 'b)) 1782 (define kc (list 'c)) 1783 (define kq (list 'q)) 1784 (define ky (list 'y)) 1785 (define kz (list 'z)) 1786 #t) 1787 (begin 1788 (define h (make-weak-eq-hashtable 32)) 1789 (and (hashtable? h) 1790 (eq-hashtable? h) 1791 (hashtable-mutable? h) 1792 (eq-hashtable-weak? h) 1793 (hashtable-weak? h))) 1794 (eq? (hashtable-hash-function h) #f) 1795 (eq? (hashtable-equivalence-function h) eq?) 1796 (equal? (hashtable-size h) 0) 1797 (equal-entries? h '#() '#()) 1798 (eqv? (eq-hashtable-set! h ka 'aval) (void)) 1799 (equal? 1800 (list 1801 (eq-hashtable-contains? h ka) 1802 (eq-hashtable-contains? h kb) 1803 (eq-hashtable-contains? h kc)) 1804 '(#t #f #f)) 1805 (eqv? (eq-hashtable-set! h kb 'bval) (void)) 1806 (equal? 1807 (list 1808 (eq-hashtable-contains? h ka) 1809 (eq-hashtable-contains? h kb) 1810 (eq-hashtable-contains? h kc)) 1811 '(#t #t #f)) 1812 (eqv? (eq-hashtable-set! h kc 'cval) (void)) 1813 (equal? 1814 (list 1815 (eq-hashtable-contains? h ka) 1816 (eq-hashtable-contains? h kb) 1817 (eq-hashtable-contains? h kc)) 1818 '(#t #t #t)) 1819 (equal? (hashtable-size h) 3) 1820 (equal-entries? h '#((a) (b) (c)) '#(aval bval cval)) 1821 (andmap weak-pair? (vector->list (hashtable-cells h))) 1822 (equal? (eq-hashtable-ref h ka 1) 'aval) 1823 (equal? (eq-hashtable-ref h kb #f) 'bval) 1824 (equal? (eq-hashtable-ref h kc 'nope) 'cval) 1825 (eqv? (eq-hashtable-delete! h kb) (void)) 1826 (equal? (hashtable-size h) 2) 1827 (equal-entries? h '#((a) (c)) '#(aval cval)) 1828 (begin 1829 (define h2 (hashtable-copy h #t)) 1830 (and (hashtable? h2) 1831 (eq-hashtable? h2) 1832 (hashtable-mutable? h2) 1833 (hashtable-weak? h2) 1834 (eq-hashtable-weak? h2))) 1835 (equal? (hashtable-size h2) 2) 1836 (equal-entries? h2 '#((a) (c)) '#(aval cval)) 1837 (eqv? (hashtable-clear! h 4) (void)) 1838 (equal? 1839 (list 1840 (hashtable-size h) 1841 (eq-hashtable-ref h ka 1) 1842 (eq-hashtable-ref h kb #f) 1843 (eq-hashtable-ref h kc 'nope)) 1844 '(0 1 #f nope)) 1845 (equal-entries? h '#() '#()) 1846 (equal? 1847 (list 1848 (hashtable-size h2) 1849 (eq-hashtable-ref h2 ka 1) 1850 (eq-hashtable-ref h2 kb #f) 1851 (eq-hashtable-ref h2 kc 'nope)) 1852 '(2 aval #f cval)) 1853 (equal-entries? h2 '#((a) (c)) '#(aval cval)) 1854 (eqv? 1855 (eq-hashtable-update! h kq 1856 (lambda (x) (+ x 1)) 1857 17) 1858 (void)) 1859 (equal? (eq-hashtable-ref h kq #f) 18) 1860 (eqv? 1861 (eq-hashtable-update! h kq 1862 (lambda (x) (+ x 1)) 1863 17) 1864 (void)) 1865 (equal? (eq-hashtable-ref h kq #f) 19) 1866 (equal? (hashtable-size h) 1) 1867 (equal-entries? h '#((q)) '#(19)) 1868 (eqv? 1869 (begin 1870 (set! kq (void)) 1871 (collect (collect-maximum-generation)) 1872 (hashtable-size h)) 1873 0) 1874 (equal-entries? h '#() '#()) 1875 (equal? (eq-hashtable-ref h ky #f) #f) 1876 (eqv? 1877 (eq-hashtable-set! h ky 'toad) 1878 (void)) 1879 (equal? (eq-hashtable-ref h ky #f) 'toad) 1880 (equal? (eq-hashtable-ref h kz #f) #f) 1881 (eqv? 1882 (eq-hashtable-update! h kz list 'frog) 1883 (void)) 1884 (equal? (eq-hashtable-ref h kz #f) '(frog)) 1885 (equal-entries? 1886 h 1887 (vector kz ky) 1888 (vector (eq-hashtable-ref h kz #f) 'toad)) 1889 (eqv? (eq-hashtable-ref h '(zippo) 'nil) 'nil) 1890 (begin 1891 (define h3 (hashtable-copy h2 #f)) 1892 (and (hashtable? h3) 1893 (eq-hashtable? h3) 1894 (not (hashtable-mutable? h3)) 1895 (eq-hashtable-weak? h3) 1896 (hashtable-weak? h3))) 1897 (equal-entries? h2 '#((a) (c)) '#(aval cval)) 1898 (equal-entries? h3 '#((a) (c)) '#(aval cval)) 1899 (equal? 1900 (begin 1901 (set! ka (void)) 1902 (collect (collect-maximum-generation)) 1903 (list (hashtable-size h2) (hashtable-size h3))) 1904 '(1 1)) 1905 (equal-entries? h2 '#((c)) '#(cval)) 1906 (equal-entries? h3 '#((c)) '#(cval)) 1907 (eqv? 1908 (begin 1909 (set! h3 (void)) 1910 (collect (collect-maximum-generation)) 1911 (hashtable-size h2)) 1912 1) 1913 (equal-entries? h2 '#((c)) '#(cval)) 1914 1915 ; test for proper shrinkage 1916 (eqv? 1917 (let ([ht (make-eq-hashtable 32)]) 1918 (for-each 1919 (lambda (k*) (for-each (lambda (k) (eq-hashtable-delete! ht k)) k*)) 1920 (let ([k** (map (lambda (x) (map list (make-list 1000))) 1921 (make-list 100))]) 1922 (for-each 1923 (lambda (k*) (map (lambda (k) (eq-hashtable-set! ht k 75)) k*)) 1924 k**) 1925 k**)) 1926 (#%$hashtable-veclen ht)) 1927 32) 1928 1929 ; test for proper shrinkage as objects are bwp'd 1930 ; uses delete to trigger final shrinkage 1931 (equal? 1932 (let* ([ht (make-weak-eq-hashtable 32)] 1933 [len (#%$hashtable-veclen ht)]) 1934 (eq-hashtable-set! ht 'a 'b) 1935 (for-each 1936 (lambda (k*) (map (lambda (k) (eq-hashtable-set! ht k 75)) k*)) 1937 (map (lambda (x) (map list (make-list 1000))) (make-list 100))) 1938 (collect (collect-maximum-generation)) 1939 (eq-hashtable-delete! ht 'a) 1940 (list (hashtable-size ht) (= (#%$hashtable-veclen ht) len))) 1941 '(0 #t)) 1942 ) 1943 1944(mat $ephemeron-eq-hashtable 1945 (begin 1946 (define ka (list 'a)) 1947 (define kb (list 'b)) 1948 (define kc (list 'c)) 1949 (define kq (list 'q)) 1950 (define ky (list 'y)) 1951 (define kz (list 'z)) 1952 #t) 1953 (begin 1954 (define h (make-ephemeron-eq-hashtable 32)) 1955 (and (hashtable? h) 1956 (eq-hashtable? h) 1957 (hashtable-mutable? h) 1958 (eq-hashtable-ephemeron? h) 1959 (hashtable-ephemeron? h))) 1960 (eq? (hashtable-hash-function h) #f) 1961 (eq? (hashtable-equivalence-function h) eq?) 1962 (equal? (hashtable-size h) 0) 1963 (equal-entries? h '#() '#()) 1964 (eqv? (eq-hashtable-set! h ka 'aval) (void)) 1965 (equal? 1966 (list 1967 (eq-hashtable-contains? h ka) 1968 (eq-hashtable-contains? h kb) 1969 (eq-hashtable-contains? h kc)) 1970 '(#t #f #f)) 1971 (eqv? (eq-hashtable-set! h kb 'bval) (void)) 1972 (equal? 1973 (list 1974 (eq-hashtable-contains? h ka) 1975 (eq-hashtable-contains? h kb) 1976 (eq-hashtable-contains? h kc)) 1977 '(#t #t #f)) 1978 (eqv? (eq-hashtable-set! h kc 'cval) (void)) 1979 (equal? 1980 (list 1981 (eq-hashtable-contains? h ka) 1982 (eq-hashtable-contains? h kb) 1983 (eq-hashtable-contains? h kc)) 1984 '(#t #t #t)) 1985 (equal? (hashtable-size h) 3) 1986 (equal-entries? h '#((a) (b) (c)) '#(aval bval cval)) 1987 (andmap ephemeron-pair? (vector->list (hashtable-cells h))) 1988 (equal? (eq-hashtable-ref h ka 1) 'aval) 1989 (equal? (eq-hashtable-ref h kb #f) 'bval) 1990 (equal? (eq-hashtable-ref h kc 'nope) 'cval) 1991 (eqv? (eq-hashtable-delete! h kb) (void)) 1992 (equal? (hashtable-size h) 2) 1993 (equal-entries? h '#((a) (c)) '#(aval cval)) 1994 (begin 1995 (define h2 (hashtable-copy h #t)) 1996 (and (hashtable? h2) 1997 (eq-hashtable? h2) 1998 (hashtable-mutable? h2) 1999 (hashtable-ephemeron? h2) 2000 (eq-hashtable-ephemeron? h2))) 2001 (equal? (hashtable-size h2) 2) 2002 (equal-entries? h2 '#((a) (c)) '#(aval cval)) 2003 (eqv? (hashtable-clear! h 4) (void)) 2004 (equal? 2005 (list 2006 (hashtable-size h) 2007 (eq-hashtable-ref h ka 1) 2008 (eq-hashtable-ref h kb #f) 2009 (eq-hashtable-ref h kc 'nope)) 2010 '(0 1 #f nope)) 2011 (equal-entries? h '#() '#()) 2012 (equal? 2013 (list 2014 (hashtable-size h2) 2015 (eq-hashtable-ref h2 ka 1) 2016 (eq-hashtable-ref h2 kb #f) 2017 (eq-hashtable-ref h2 kc 'nope)) 2018 '(2 aval #f cval)) 2019 (equal-entries? h2 '#((a) (c)) '#(aval cval)) 2020 (eqv? 2021 (eq-hashtable-update! h kq 2022 (lambda (x) (+ x 1)) 2023 17) 2024 (void)) 2025 (equal? (eq-hashtable-ref h kq #f) 18) 2026 (eqv? 2027 (eq-hashtable-update! h kq 2028 (lambda (x) (+ x 1)) 2029 17) 2030 (void)) 2031 (equal? (eq-hashtable-ref h kq #f) 19) 2032 (equal? (hashtable-size h) 1) 2033 (equal-entries? h '#((q)) '#(19)) 2034 (eqv? 2035 (begin 2036 (set! kq (void)) 2037 (collect (collect-maximum-generation)) 2038 (hashtable-size h)) 2039 0) 2040 (equal-entries? h '#() '#()) 2041 (equal? (eq-hashtable-ref h ky #f) #f) 2042 (eqv? 2043 (eq-hashtable-set! h ky 'toad) 2044 (void)) 2045 (equal? (eq-hashtable-ref h ky #f) 'toad) 2046 (equal? (eq-hashtable-ref h kz #f) #f) 2047 (eqv? 2048 (eq-hashtable-update! h kz list 'frog) 2049 (void)) 2050 (equal? (eq-hashtable-ref h kz #f) '(frog)) 2051 (equal-entries? 2052 h 2053 (vector kz ky) 2054 (vector (eq-hashtable-ref h kz #f) 'toad)) 2055 (eqv? (eq-hashtable-ref h '(zippo) 'nil) 'nil) 2056 (begin 2057 (define h3 (hashtable-copy h2 #f)) 2058 (and (hashtable? h3) 2059 (eq-hashtable? h3) 2060 (not (hashtable-mutable? h3)) 2061 (eq-hashtable-ephemeron? h3) 2062 (hashtable-ephemeron? h3))) 2063 (equal-entries? h2 '#((a) (c)) '#(aval cval)) 2064 (equal-entries? h3 '#((a) (c)) '#(aval cval)) 2065 (equal? 2066 (begin 2067 (set! ka (void)) 2068 (collect (collect-maximum-generation)) 2069 (list (hashtable-size h2) (hashtable-size h3))) 2070 '(1 1)) 2071 (equal-entries? h2 '#((c)) '#(cval)) 2072 (equal-entries? h3 '#((c)) '#(cval)) 2073 (eqv? 2074 (begin 2075 (set! h3 (void)) 2076 (collect (collect-maximum-generation)) 2077 (hashtable-size h2)) 2078 1) 2079 (equal-entries? h2 '#((c)) '#(cval)) 2080 2081 ; test for proper shrinkage 2082 (eqv? 2083 (let ([ht (make-eq-hashtable 32)]) 2084 (for-each 2085 (lambda (k*) (for-each (lambda (k) (eq-hashtable-delete! ht k)) k*)) 2086 (let ([k** (map (lambda (x) (map list (make-list 1000))) 2087 (make-list 100))]) 2088 (for-each 2089 (lambda (k*) (map (lambda (k) (eq-hashtable-set! ht k 75)) k*)) 2090 k**) 2091 k**)) 2092 (#%$hashtable-veclen ht)) 2093 32) 2094 2095 ; test for proper shrinkage as objects are bwp'd 2096 ; uses delete to trigger final shrinkage 2097 (equal? 2098 (let* ([ht (make-ephemeron-eq-hashtable 32)] 2099 [len (#%$hashtable-veclen ht)]) 2100 (eq-hashtable-set! ht 'a 'b) 2101 (for-each 2102 (lambda (k*) (map (lambda (k) (eq-hashtable-set! ht k 75)) k*)) 2103 (map (lambda (x) (map list (make-list 1000))) (make-list 100))) 2104 (collect (collect-maximum-generation)) 2105 (eq-hashtable-delete! ht 'a) 2106 (list (hashtable-size ht) (= (#%$hashtable-veclen ht) len))) 2107 '(0 #t)) 2108) 2109 2110(mat eq-strange 2111 (begin 2112 (define $ht (make-eq-hashtable)) 2113 (define $wht (make-weak-eq-hashtable)) 2114 (define $eht (make-ephemeron-eq-hashtable)) 2115 (and (hashtable? $ht) 2116 (eq-hashtable? $ht) 2117 (hashtable? $wht) 2118 (eq-hashtable? $wht) 2119 (hashtable? $eht) 2120 (eq-hashtable? $eht))) 2121 (eqv? (hashtable-set! $ht #f 75) (void)) 2122 (eqv? (hashtable-ref $ht #f 80) 75) 2123 (eqv? (hashtable-set! $wht #f 75) (void)) 2124 (eqv? (hashtable-ref $wht #f 80) 75) 2125 (eqv? (hashtable-set! $eht #f 75) (void)) 2126 (eqv? (hashtable-ref $eht #f 80) 75) 2127 (eqv? (hashtable-set! $ht #!bwp "hello") (void)) 2128 (equal? (hashtable-ref $ht #!bwp "goodbye") "hello") 2129 (eqv? (hashtable-set! $wht #!bwp "hello") (void)) 2130 (and (member (hashtable-ref $wht #!bwp "goodbye") '("hello" "goodbye")) #t) 2131 (eqv? (hashtable-set! $eht #!bwp "hello") (void)) 2132 (and (member (hashtable-ref $eht #!bwp "goodbye") '("hello" "goodbye")) #t) 2133 ; make sure that association isn't added before procedure is called 2134 (equal? 2135 (begin 2136 (hashtable-update! $ht 'cupie 2137 (lambda (x) (hashtable-ref $ht 'cupie (cons 'barbie x))) 2138 'doll) 2139 (hashtable-ref $ht 'cupie 'oops)) 2140 '(barbie . doll)) 2141 (equal? 2142 (begin 2143 (hashtable-update! $wht 'cupie 2144 (lambda (x) (hashtable-ref $wht 'cupie (cons 'barbie x))) 2145 'doll) 2146 (hashtable-ref $wht 'cupie 'oops)) 2147 '(barbie . doll)) 2148 (equal? 2149 (begin 2150 (hashtable-update! $eht 'cupie 2151 (lambda (x) (hashtable-ref $eht 'cupie (cons 'barbie x))) 2152 'doll) 2153 (hashtable-ref $eht 'cupie 'oops)) 2154 '(barbie . doll)) 2155) 2156 2157(mat eq-hashtable-stress 2158 ; stress tests 2159 (let () ; nonweak 2160 (define pick 2161 (lambda (ls) 2162 (list-ref ls (random (length ls))))) 2163 (define ht (make-eq-hashtable 4)) 2164 (let ([ls (remq '|| (oblist))] [n 50000]) 2165 (let f ([i 0] [keep '()] [drop '()]) 2166 (if (= i n) 2167 (and (= (hashtable-size ht) (- n (length drop))) 2168 (andmap (lambda (k) 2169 (string=? 2170 (symbol->string (hashtable-ref ht k #f)) 2171 (cond 2172 [(string? k) k] 2173 [(pair? k) (car k)] 2174 [(vector? k) (vector-ref k 0)]))) 2175 keep) 2176 (andmap (lambda (k) (eq? (hashtable-ref ht k 'no) 'no)) 2177 drop)) 2178 (let* ([x (pick ls)] [s (string-copy (symbol->string x))]) 2179 (let ([k (case (pick '(string pair vector)) 2180 [(string) s] 2181 [(pair) (list s)] 2182 [(vector) (vector s)])]) 2183 (hashtable-set! ht k x) 2184 (let ([keep (if (= (modulo i 5) 0) (cons k keep) keep)]) 2185 (if (= (modulo i 17) 5) 2186 (let ([k (pick keep)]) 2187 (hashtable-delete! ht k) 2188 (let ([drop (cons k drop)]) 2189 (when (= (random 5) 3) 2190 (hashtable-delete! ht (pick drop))) 2191 (f (+ i 1) (remq k keep) drop))) 2192 (f (+ i 1) keep drop))))))))) 2193 2194 (let () ; weak 2195 (define pick 2196 (lambda (ls) 2197 (list-ref ls (random (length ls))))) 2198 (define ht (make-weak-eq-hashtable 4)) 2199 (let ([ls (remq '|| (oblist))] [n 50000]) 2200 (let f ([i 0] [keep '()] [drop '()]) 2201 (if (= i n) 2202 (and (<= (hashtable-size ht) (- n (length drop))) 2203 (begin 2204 (collect (collect-maximum-generation)) 2205 (= (hashtable-size ht) (length keep))) 2206 (andmap (lambda (k) 2207 (string=? 2208 (symbol->string (hashtable-ref ht k #f)) 2209 (cond 2210 [(string? k) k] 2211 [(pair? k) (car k)] 2212 [(vector? k) (vector-ref k 0)]))) 2213 keep) 2214 (andmap (lambda (k) (eq? (hashtable-ref ht k 'no) 'no)) 2215 drop)) 2216 (let* ([x (pick ls)] [s (string-copy (symbol->string x))]) 2217 (let ([k (case (pick '(string pair vector)) 2218 [(string) s] 2219 [(pair) (list s)] 2220 [(vector) (vector s)])]) 2221 (hashtable-set! ht k x) 2222 (let ([keep (if (= (modulo i 5) 0) (cons k keep) keep)]) 2223 (if (= (modulo i 17) 5) 2224 (let ([k (pick keep)]) 2225 (hashtable-delete! ht k) 2226 (let ([drop (cons k drop)]) 2227 (when (= (random 5) 3) 2228 (hashtable-delete! ht (pick drop))) 2229 (f (+ i 1) (remq k keep) drop))) 2230 (f (+ i 1) keep drop))))))))) 2231 2232 (let () ; ephemeron 2233 (define pick 2234 (lambda (ls) 2235 (list-ref ls (random (length ls))))) 2236 (define ht (make-ephemeron-eq-hashtable 4)) 2237 (let ([ls (remq '|| (oblist))] [n 50000]) 2238 (let f ([i 0] [keep '()] [drop '()]) 2239 (if (= i n) 2240 (and (<= (hashtable-size ht) (- n (length drop))) 2241 (begin 2242 (collect (collect-maximum-generation)) 2243 (= (hashtable-size ht) (length keep))) 2244 (andmap (lambda (k) 2245 (string=? 2246 (symbol->string (hashtable-ref ht k #f)) 2247 (cond 2248 [(string? k) k] 2249 [(pair? k) (car k)] 2250 [(vector? k) (vector-ref k 0)]))) 2251 keep) 2252 (andmap (lambda (k) (eq? (hashtable-ref ht k 'no) 'no)) 2253 drop)) 2254 (let* ([x (pick ls)] [s (string-copy (symbol->string x))]) 2255 (let ([k (case (pick '(string pair vector)) 2256 [(string) s] 2257 [(pair) (list s)] 2258 [(vector) (vector s)])]) 2259 (hashtable-set! ht k x) 2260 (let ([keep (if (= (modulo i 5) 0) (cons k keep) keep)]) 2261 (if (= (modulo i 17) 5) 2262 (let ([k (pick keep)]) 2263 (hashtable-delete! ht k) 2264 (let ([drop (cons k drop)]) 2265 (when (= (random 5) 3) 2266 (hashtable-delete! ht (pick drop))) 2267 (f (+ i 1) (remq k keep) drop))) 2268 (f (+ i 1) keep drop))))))))) 2269 2270) 2271 2272(mat nonweak-eqv-hashtable 2273 (begin 2274 (define h (make-eqv-hashtable 32)) 2275 (and (hashtable? h) 2276 (not (eq-hashtable? h)) 2277 (hashtable-mutable? h) 2278 (not (hashtable-weak? h)) 2279 (not (hashtable-ephemeron? h)))) 2280 (eq? (hashtable-hash-function h) #f) 2281 (eq? (hashtable-equivalence-function h) eqv?) 2282 (equal? (hashtable-size h) 0) 2283 (equal-entries? h '#() '#()) 2284 (eqv? (hashtable-set! h 'a 'aval) (void)) 2285 (equal? 2286 (list 2287 (hashtable-contains? h 'a) 2288 (hashtable-contains? h 3.4) 2289 (hashtable-contains? h 'c)) 2290 '(#t #f #f)) 2291 (eqv? (hashtable-set! h 3.4 'bval) (void)) 2292 (equal? 2293 (list 2294 (hashtable-contains? h 'a) 2295 (hashtable-contains? h 3.4) 2296 (hashtable-contains? h 'c)) 2297 '(#t #t #f)) 2298 (eqv? (hashtable-set! h 'c 'cval) (void)) 2299 (equal? 2300 (list 2301 (hashtable-contains? h 'a) 2302 (hashtable-contains? h 3.4) 2303 (hashtable-contains? h 'c)) 2304 '(#t #t #t)) 2305 (equal? (hashtable-size h) 3) 2306 (equal-entries? h '#(3.4 c a) '#(bval cval aval)) 2307 #;(same-elements? (list->vector (hashtable-map h cons)) '#((a . aval) (3.4 . bval) (c . cval))) 2308 #;(same-elements? 2309 (let ([v (make-vector 3)] [i 0]) 2310 (hashtable-for-each h (lambda (key val) (vector-set! v i (cons key val)) (set! i (fx+ i 1)))) 2311 v) 2312 '#((a . aval) (3.4 . bval) (c . cval))) 2313 #;(same-elements? 2314 (let ([v (make-vector 3)] [i 0]) 2315 (hashtable-for-each-cell h (lambda (a) (vector-set! v i a) (set! i (fx+ i 1)))) 2316 v) 2317 '#((a . aval) (3.4 . bval) (c . cval))) 2318 (equal? (hashtable-ref h 'a 1) 'aval) 2319 (equal? (hashtable-ref h 3.4 #f) 'bval) 2320 (equal? (hashtable-ref h 'c 'nope) 'cval) 2321 (eqv? (hashtable-delete! h 3.4) (void)) 2322 (equal? (hashtable-size h) 2) 2323 (equal-entries? h '#(a c) '#(aval cval)) 2324 (begin 2325 (define h2 (hashtable-copy h #t)) 2326 (and (hashtable? h2) 2327 (hashtable-mutable? h2) 2328 (not (hashtable-weak? h2)) 2329 (not (hashtable-ephemeron? h2)))) 2330 (eq? (hashtable-hash-function h2) #f) 2331 (eq? (hashtable-equivalence-function h2) eqv?) 2332 (equal? (hashtable-size h2) 2) 2333 (equal-entries? h2 '#(a c) '#(aval cval)) 2334 (eqv? (hashtable-clear! h 4) (void)) 2335 (equal? 2336 (list 2337 (hashtable-size h) 2338 (hashtable-ref h 'a 1) 2339 (hashtable-ref h 3.4 #f) 2340 (hashtable-ref h 'c 'nope)) 2341 '(0 1 #f nope)) 2342 (equal-entries? h '#() '#()) 2343 (equal? 2344 (list 2345 (hashtable-size h2) 2346 (hashtable-ref h2 'a 1) 2347 (hashtable-ref h2 3.4 #f) 2348 (hashtable-ref h2 'c 'nope)) 2349 '(2 aval #f cval)) 2350 (equal-entries? h2 '#(a c) '#(aval cval)) 2351 (eqv? 2352 (hashtable-update! h 'q 2353 (lambda (x) (+ x 1)) 2354 17) 2355 (void)) 2356 (equal? (hashtable-ref h 'q #f) 18) 2357 (eqv? 2358 (hashtable-update! h 'q 2359 (lambda (x) (+ x 1)) 2360 17) 2361 (void)) 2362 (equal? (hashtable-ref h 'q #f) 19) 2363 (equal? (hashtable-size h) 1) 2364 ; test hashtable-copy when some keys may have moved 2365 (let ([t (parameterize ([collect-request-handler void]) 2366 (let ([h4a (make-eqv-hashtable 32)] 2367 [k* (map list (make-list 100))]) 2368 (for-each (lambda (x) (hashtable-set! h4a x x)) k*) 2369 (collect) 2370 ; create copy after collection but before otherwise touching h4a 2371 (let ([h4b (hashtable-copy h4a #t)]) 2372 (andmap 2373 (lambda (k) (eqv? (hashtable-ref h4b k #f) k)) 2374 k*))))]) 2375 (collect) 2376 t) 2377 2378 ; test for proper shrinkage 2379 (equal? 2380 (let ([ht (make-eqv-hashtable 32)]) 2381 (for-each 2382 (lambda (k*) (for-each (lambda (k) (hashtable-delete! ht k)) k*)) 2383 (let ([k** (map (lambda (x) (map list (make-list 1000))) 2384 (make-list 100))]) 2385 (for-each 2386 (lambda (k*) (map (lambda (k) (hashtable-set! ht k 75)) k*)) 2387 k**) 2388 k**)) 2389 (call-with-values (lambda () (#%$hashtable-veclen ht)) cons)) 2390 '(32 . 32)) 2391) 2392 2393(mat weak-eqv-hashtable 2394 (begin 2395 (define ka (list 'a)) 2396 (define kb (list 'b)) 2397 (define kc (list 'c)) 2398 (define kq (list 'q)) 2399 (define ky (list 'y)) 2400 (define kz (list 'z)) 2401 (define km -5.75) 2402 (define kn 17) 2403 (define ko (+ (most-positive-fixnum) 5)) 2404 #t) 2405 (begin 2406 (define h (make-weak-eqv-hashtable 32)) 2407 (and (hashtable? h) 2408 (not (eq-hashtable? h)) 2409 (hashtable-mutable? h) 2410 (hashtable-weak? h))) 2411 (eq? (hashtable-hash-function h) #f) 2412 (eq? (hashtable-equivalence-function h) eqv?) 2413 (equal? (hashtable-size h) 0) 2414 (equal-entries? h '#() '#()) 2415 (eqv? (hashtable-set! h ka 'aval) (void)) 2416 (equal? 2417 (list 2418 (hashtable-contains? h ka) 2419 (hashtable-contains? h kb) 2420 (hashtable-contains? h kc) 2421 (hashtable-contains? h km) 2422 (hashtable-contains? h kn) 2423 (hashtable-contains? h ko)) 2424 '(#t #f #f #f #f #f)) 2425 (eqv? (hashtable-set! h kb 'bval) (void)) 2426 (equal? 2427 (list 2428 (hashtable-contains? h ka) 2429 (hashtable-contains? h kb) 2430 (hashtable-contains? h kc) 2431 (hashtable-contains? h km) 2432 (hashtable-contains? h kn) 2433 (hashtable-contains? h ko)) 2434 '(#t #t #f #f #f #f)) 2435 (eqv? (hashtable-set! h kc 'cval) (void)) 2436 (equal? 2437 (list 2438 (hashtable-contains? h ka) 2439 (hashtable-contains? h kb) 2440 (hashtable-contains? h kc) 2441 (hashtable-contains? h km) 2442 (hashtable-contains? h kn) 2443 (hashtable-contains? h ko)) 2444 '(#t #t #t #f #f #f)) 2445 (eqv? (hashtable-set! h km 'mval) (void)) 2446 (equal? 2447 (list 2448 (hashtable-contains? h ka) 2449 (hashtable-contains? h kb) 2450 (hashtable-contains? h kc) 2451 (hashtable-contains? h km) 2452 (hashtable-contains? h kn) 2453 (hashtable-contains? h ko)) 2454 '(#t #t #t #t #f #f)) 2455 (eqv? (hashtable-set! h kn 'nval) (void)) 2456 (equal? 2457 (list 2458 (hashtable-contains? h ka) 2459 (hashtable-contains? h kb) 2460 (hashtable-contains? h kc) 2461 (hashtable-contains? h km) 2462 (hashtable-contains? h kn) 2463 (hashtable-contains? h ko)) 2464 '(#t #t #t #t #t #f)) 2465 (eqv? (hashtable-set! h ko 'oval) (void)) 2466 (equal? 2467 (list 2468 (hashtable-contains? h ka) 2469 (hashtable-contains? h kb) 2470 (hashtable-contains? h kc) 2471 (hashtable-contains? h km) 2472 (hashtable-contains? h kn) 2473 (hashtable-contains? h ko)) 2474 '(#t #t #t #t #t #t)) 2475 (equal? (hashtable-size h) 6) 2476 (equal-entries? h `#((a) (b) (c) -5.75 17 ,ko) '#(aval bval cval mval nval oval)) 2477 #;(same-elements? 2478 (list->vector (hashtable-map h cons)) 2479 `#(((a) . aval) ((b) . bval) ((c) . cval) (-5.75 . mval) (17 . nval) (,ko . oval))) 2480 #;(same-elements? 2481 (let ([v (make-vector 6)] [i 0]) 2482 (hashtable-for-each h (lambda (key val) (vector-set! v i (cons key val)) (set! i (fx+ i 1)))) 2483 v) 2484 `#(((a) . aval) ((b) . bval) ((c) . cval) (-5.75 . mval) (17 . nval) (,ko . oval))) 2485 #;(same-elements? 2486 (let ([v (make-vector 6)] [i 0]) 2487 (hashtable-for-each-cell h (lambda (a) (vector-set! v i a) (set! i (fx+ i 1)))) 2488 v) 2489 `#(((a) . aval) ((b) . bval) ((c) . cval) (-5.75 . mval) (17 . nval) (,ko . oval))) 2490 (eq? (hashtable-ref h ka 1) 'aval) 2491 (eq? (hashtable-ref h kb #f) 'bval) 2492 (eq? (hashtable-ref h kc 'nope) 'cval) 2493 (eq? (hashtable-ref h (+ 2 -7.75) 'ugh) 'mval) 2494 (eq? (hashtable-ref h (/ 34 2) 'ugh) 'nval) 2495 (eq? (hashtable-ref h (+ (most-positive-fixnum) 7 -2) 'ugh) 'oval) 2496 (eqv? (hashtable-delete! h kb) (void)) 2497 (equal? (hashtable-size h) 5) 2498 (equal-entries? h `#((a) (c) -5.75 17 ,ko) '#(aval cval mval nval oval)) 2499 (begin 2500 (define h2 (hashtable-copy h #t)) 2501 (and (hashtable? h2) 2502 (hashtable-mutable? h2) 2503 (hashtable-weak? h2))) 2504 (eq? (hashtable-hash-function h2) #f) 2505 (eq? (hashtable-equivalence-function h2) eqv?) 2506 (equal? (hashtable-size h2) 5) 2507 (equal-entries? h `#((a) (c) -5.75 17 ,ko) '#(aval cval mval nval oval)) 2508 (eqv? (hashtable-clear! h 4) (void)) 2509 (equal? 2510 (list 2511 (hashtable-size h) 2512 (hashtable-ref h ka 1) 2513 (hashtable-ref h kb #f) 2514 (hashtable-ref h kc 'nope) 2515 (hashtable-ref h km 'nope) 2516 (hashtable-ref h kn 'nope) 2517 (hashtable-ref h ko 'nope)) 2518 '(0 1 #f nope nope nope nope)) 2519 (equal-entries? h '#() '#()) 2520 (equal? 2521 (list 2522 (hashtable-size h2) 2523 (hashtable-ref h2 ka 1) 2524 (hashtable-ref h2 kb #f) 2525 (hashtable-ref h2 kc 'nope) 2526 (hashtable-ref h2 (- (+ km 1) 1) 'nope) 2527 (hashtable-ref h2 (- (+ kn 1) 1) 'nope) 2528 (hashtable-ref h2 (- (+ ko 1) 1) 'nope)) 2529 '(5 aval #f cval mval nval oval)) 2530 (equal-entries? h2 `#((a) (c) -5.75 17 ,ko) '#(aval cval mval nval oval)) 2531 (eqv? 2532 (hashtable-update! h kq 2533 (lambda (x) (+ x 1)) 2534 17) 2535 (void)) 2536 (equal? (hashtable-ref h kq #f) 18) 2537 (eqv? 2538 (hashtable-update! h kq 2539 (lambda (x) (+ x 1)) 2540 17) 2541 (void)) 2542 (equal? (hashtable-ref h kq #f) 19) 2543 (equal? (hashtable-size h) 1) 2544 (equal-entries? h '#((q)) '#(19)) 2545 (eqv? 2546 (begin 2547 (set! kq (void)) 2548 (collect (collect-maximum-generation)) 2549 (hashtable-size h)) 2550 0) 2551 (equal-entries? h '#() '#()) 2552 (equal? (hashtable-ref h ky #f) #f) 2553 (eqv? 2554 (hashtable-set! h ky 'toad) 2555 (void)) 2556 (equal? (hashtable-ref h ky #f) 'toad) 2557 (equal? (hashtable-ref h kz #f) #f) 2558 (eqv? 2559 (hashtable-update! h kz list 'frog) 2560 (void)) 2561 (equal? (hashtable-ref h kz #f) '(frog)) 2562 (equal-entries? 2563 h 2564 (vector kz ky) 2565 (vector (hashtable-ref h kz #f) 'toad)) 2566 (eqv? (hashtable-ref h '(zippo) 'nil) 'nil) 2567 (begin 2568 (define h3 (hashtable-copy h2 #f)) 2569 (and (hashtable? h3) 2570 (not (hashtable-mutable? h3)) 2571 (hashtable-weak? h3))) 2572 (equal-entries? h2 `#((a) (c) -5.75 17 ,ko) '#(aval cval mval nval oval)) 2573 (equal-entries? h3 `#((a) (c) -5.75 17 ,ko) '#(aval cval mval nval oval)) 2574 (equal? 2575 (begin 2576 (set! ka (void)) 2577 (set! km (void)) 2578 (set! kn (void)) 2579 (set! ko (void)) 2580 (collect (collect-maximum-generation)) 2581 (list (hashtable-size h2) (hashtable-size h3))) 2582 '(4 4)) 2583 (equal-entries? h2 `#((c) -5.75 17 ,(+ (most-positive-fixnum) 5)) '#(cval mval nval oval)) 2584 (equal-entries? h3 `#((c) -5.75 17 ,(+ (most-positive-fixnum) 5)) '#(cval mval nval oval)) 2585 (eqv? 2586 (begin 2587 (set! h3 (void)) 2588 (collect (collect-maximum-generation)) 2589 (hashtable-size h2)) 2590 4) 2591 (equal-entries? h2 `#((c) -5.75 17 ,(+ (most-positive-fixnum) 5)) '#(cval mval nval oval)) 2592 2593 ; test for proper shrinkage 2594 (equal? 2595 (let ([ht (make-eqv-hashtable 32)]) 2596 (for-each 2597 (lambda (k*) (for-each (lambda (k) (hashtable-delete! ht k)) k*)) 2598 (let ([k** (map (lambda (x) (map list (make-list 1000))) 2599 (make-list 100))]) 2600 (for-each 2601 (lambda (k*) (map (lambda (k) (hashtable-set! ht k 75)) k*)) 2602 k**) 2603 k**)) 2604 (call-with-values (lambda () (#%$hashtable-veclen ht)) cons)) 2605 '(32 . 32)) 2606 2607 ; test for proper shrinkage as objects are bwp'd 2608 ; uses delete to trigger final shrinkage 2609 (equal? 2610 (let ([ht (make-weak-eqv-hashtable 32)]) 2611 (hashtable-set! ht 'a 'b) 2612 (for-each 2613 (lambda (k*) (map (lambda (k) (hashtable-set! ht k 75)) k*)) 2614 (map (lambda (x) (map list (make-list 1000))) (make-list 100))) 2615 (collect (collect-maximum-generation)) 2616 (hashtable-delete! ht 'a) 2617 (list (hashtable-size ht) 2618 (let-values ([(n1 n2) (#%$hashtable-veclen ht)]) 2619 (= n1 n2 32)))) 2620 '(0 #t)) 2621 ) 2622 2623(mat ephemeron-eqv-hashtable 2624 (begin 2625 (define ka (list 'a)) 2626 (define kb (list 'b)) 2627 (define kc (list 'c)) 2628 (define kq (list 'q)) 2629 (define ky (list 'y)) 2630 (define kz (list 'z)) 2631 (define km -5.75) 2632 (define kn 17) 2633 (define ko (+ (most-positive-fixnum) 5)) 2634 #t) 2635 (begin 2636 (define h (make-ephemeron-eqv-hashtable 32)) 2637 (and (hashtable? h) 2638 (not (eq-hashtable? h)) 2639 (hashtable-mutable? h) 2640 (hashtable-ephemeron? h))) 2641 (eq? (hashtable-hash-function h) #f) 2642 (eq? (hashtable-equivalence-function h) eqv?) 2643 (equal? (hashtable-size h) 0) 2644 (equal-entries? h '#() '#()) 2645 (eqv? (hashtable-set! h ka 'aval) (void)) 2646 (equal? 2647 (list 2648 (hashtable-contains? h ka) 2649 (hashtable-contains? h kb) 2650 (hashtable-contains? h kc) 2651 (hashtable-contains? h km) 2652 (hashtable-contains? h kn) 2653 (hashtable-contains? h ko)) 2654 '(#t #f #f #f #f #f)) 2655 (eqv? (hashtable-set! h kb 'bval) (void)) 2656 (equal? 2657 (list 2658 (hashtable-contains? h ka) 2659 (hashtable-contains? h kb) 2660 (hashtable-contains? h kc) 2661 (hashtable-contains? h km) 2662 (hashtable-contains? h kn) 2663 (hashtable-contains? h ko)) 2664 '(#t #t #f #f #f #f)) 2665 (eqv? (hashtable-set! h kc 'cval) (void)) 2666 (equal? 2667 (list 2668 (hashtable-contains? h ka) 2669 (hashtable-contains? h kb) 2670 (hashtable-contains? h kc) 2671 (hashtable-contains? h km) 2672 (hashtable-contains? h kn) 2673 (hashtable-contains? h ko)) 2674 '(#t #t #t #f #f #f)) 2675 (eqv? (hashtable-set! h km 'mval) (void)) 2676 (equal? 2677 (list 2678 (hashtable-contains? h ka) 2679 (hashtable-contains? h kb) 2680 (hashtable-contains? h kc) 2681 (hashtable-contains? h km) 2682 (hashtable-contains? h kn) 2683 (hashtable-contains? h ko)) 2684 '(#t #t #t #t #f #f)) 2685 (eqv? (hashtable-set! h kn 'nval) (void)) 2686 (equal? 2687 (list 2688 (hashtable-contains? h ka) 2689 (hashtable-contains? h kb) 2690 (hashtable-contains? h kc) 2691 (hashtable-contains? h km) 2692 (hashtable-contains? h kn) 2693 (hashtable-contains? h ko)) 2694 '(#t #t #t #t #t #f)) 2695 (eqv? (hashtable-set! h ko 'oval) (void)) 2696 (equal? 2697 (list 2698 (hashtable-contains? h ka) 2699 (hashtable-contains? h kb) 2700 (hashtable-contains? h kc) 2701 (hashtable-contains? h km) 2702 (hashtable-contains? h kn) 2703 (hashtable-contains? h ko)) 2704 '(#t #t #t #t #t #t)) 2705 (equal? (hashtable-size h) 6) 2706 (equal-entries? h `#((a) (b) (c) -5.75 17 ,ko) '#(aval bval cval mval nval oval)) 2707 #;(same-elements? 2708 (list->vector (hashtable-map h cons)) 2709 `#(((a) . aval) ((b) . bval) ((c) . cval) (-5.75 . mval) (17 . nval) (,ko . oval))) 2710 #;(same-elements? 2711 (let ([v (make-vector 6)] [i 0]) 2712 (hashtable-for-each h (lambda (key val) (vector-set! v i (cons key val)) (set! i (fx+ i 1)))) 2713 v) 2714 `#(((a) . aval) ((b) . bval) ((c) . cval) (-5.75 . mval) (17 . nval) (,ko . oval))) 2715 #;(same-elements? 2716 (let ([v (make-vector 6)] [i 0]) 2717 (hashtable-for-each-cell h (lambda (a) (vector-set! v i a) (set! i (fx+ i 1)))) 2718 v) 2719 `#(((a) . aval) ((b) . bval) ((c) . cval) (-5.75 . mval) (17 . nval) (,ko . oval))) 2720 (eq? (hashtable-ref h ka 1) 'aval) 2721 (eq? (hashtable-ref h kb #f) 'bval) 2722 (eq? (hashtable-ref h kc 'nope) 'cval) 2723 (eq? (hashtable-ref h (+ 2 -7.75) 'ugh) 'mval) 2724 (eq? (hashtable-ref h (/ 34 2) 'ugh) 'nval) 2725 (eq? (hashtable-ref h (+ (most-positive-fixnum) 7 -2) 'ugh) 'oval) 2726 (eqv? (hashtable-delete! h kb) (void)) 2727 (equal? (hashtable-size h) 5) 2728 (equal-entries? h `#((a) (c) -5.75 17 ,ko) '#(aval cval mval nval oval)) 2729 (begin 2730 (define h2 (hashtable-copy h #t)) 2731 (and (hashtable? h2) 2732 (hashtable-mutable? h2) 2733 (hashtable-ephemeron? h2))) 2734 (eq? (hashtable-hash-function h2) #f) 2735 (eq? (hashtable-equivalence-function h2) eqv?) 2736 (equal? (hashtable-size h2) 5) 2737 (equal-entries? h `#((a) (c) -5.75 17 ,ko) '#(aval cval mval nval oval)) 2738 (eqv? (hashtable-clear! h 4) (void)) 2739 (equal? 2740 (list 2741 (hashtable-size h) 2742 (hashtable-ref h ka 1) 2743 (hashtable-ref h kb #f) 2744 (hashtable-ref h kc 'nope) 2745 (hashtable-ref h km 'nope) 2746 (hashtable-ref h kn 'nope) 2747 (hashtable-ref h ko 'nope)) 2748 '(0 1 #f nope nope nope nope)) 2749 (equal-entries? h '#() '#()) 2750 (equal? 2751 (list 2752 (hashtable-size h2) 2753 (hashtable-ref h2 ka 1) 2754 (hashtable-ref h2 kb #f) 2755 (hashtable-ref h2 kc 'nope) 2756 (hashtable-ref h2 (- (+ km 1) 1) 'nope) 2757 (hashtable-ref h2 (- (+ kn 1) 1) 'nope) 2758 (hashtable-ref h2 (- (+ ko 1) 1) 'nope)) 2759 '(5 aval #f cval mval nval oval)) 2760 (equal-entries? h2 `#((a) (c) -5.75 17 ,ko) '#(aval cval mval nval oval)) 2761 (eqv? 2762 (hashtable-update! h kq 2763 (lambda (x) (+ x 1)) 2764 17) 2765 (void)) 2766 (equal? (hashtable-ref h kq #f) 18) 2767 (eqv? 2768 (hashtable-update! h kq 2769 (lambda (x) (+ x 1)) 2770 17) 2771 (void)) 2772 (equal? (hashtable-ref h kq #f) 19) 2773 (equal? (hashtable-size h) 1) 2774 (equal-entries? h '#((q)) '#(19)) 2775 (eqv? 2776 (begin 2777 (set! kq (void)) 2778 (collect (collect-maximum-generation)) 2779 (hashtable-size h)) 2780 0) 2781 (equal-entries? h '#() '#()) 2782 (equal? (hashtable-ref h ky #f) #f) 2783 (eqv? 2784 (hashtable-set! h ky 'toad) 2785 (void)) 2786 (equal? (hashtable-ref h ky #f) 'toad) 2787 (equal? (hashtable-ref h kz #f) #f) 2788 (eqv? 2789 (hashtable-update! h kz list 'frog) 2790 (void)) 2791 (equal? (hashtable-ref h kz #f) '(frog)) 2792 (equal-entries? 2793 h 2794 (vector kz ky) 2795 (vector (hashtable-ref h kz #f) 'toad)) 2796 (eqv? (hashtable-ref h '(zippo) 'nil) 'nil) 2797 (begin 2798 (define h3 (hashtable-copy h2 #f)) 2799 (and (hashtable? h3) 2800 (not (hashtable-mutable? h3)) 2801 (hashtable-ephemeron? h3))) 2802 (equal-entries? h2 `#((a) (c) -5.75 17 ,ko) '#(aval cval mval nval oval)) 2803 (equal-entries? h3 `#((a) (c) -5.75 17 ,ko) '#(aval cval mval nval oval)) 2804 (equal? 2805 (begin 2806 (set! ka (void)) 2807 (set! km (void)) 2808 (set! kn (void)) 2809 (set! ko (void)) 2810 (collect (collect-maximum-generation)) 2811 (list (hashtable-size h2) (hashtable-size h3))) 2812 '(4 4)) 2813 (equal-entries? h2 `#((c) -5.75 17 ,(+ (most-positive-fixnum) 5)) '#(cval mval nval oval)) 2814 (equal-entries? h3 `#((c) -5.75 17 ,(+ (most-positive-fixnum) 5)) '#(cval mval nval oval)) 2815 (eqv? 2816 (begin 2817 (set! h3 (void)) 2818 (collect (collect-maximum-generation)) 2819 (hashtable-size h2)) 2820 4) 2821 (equal-entries? h2 `#((c) -5.75 17 ,(+ (most-positive-fixnum) 5)) '#(cval mval nval oval)) 2822 2823 ; test for proper shrinkage 2824 (equal? 2825 (let ([ht (make-eqv-hashtable 32)]) 2826 (for-each 2827 (lambda (k*) (for-each (lambda (k) (hashtable-delete! ht k)) k*)) 2828 (let ([k** (map (lambda (x) (map list (make-list 1000))) 2829 (make-list 100))]) 2830 (for-each 2831 (lambda (k*) (map (lambda (k) (hashtable-set! ht k 75)) k*)) 2832 k**) 2833 k**)) 2834 (call-with-values (lambda () (#%$hashtable-veclen ht)) cons)) 2835 '(32 . 32)) 2836 2837 ; test for proper shrinkage as objects are bwp'd 2838 ; uses delete to trigger final shrinkage 2839 (equal? 2840 (let ([ht (make-ephemeron-eqv-hashtable 32)]) 2841 (hashtable-set! ht 'a 'b) 2842 (for-each 2843 (lambda (k*) (map (lambda (k) (hashtable-set! ht k 75)) k*)) 2844 (map (lambda (x) (map list (make-list 1000))) (make-list 100))) 2845 (collect (collect-maximum-generation)) 2846 (hashtable-delete! ht 'a) 2847 (list (hashtable-size ht) 2848 (let-values ([(n1 n2) (#%$hashtable-veclen ht)]) 2849 (= n1 n2 32)))) 2850 '(0 #t)) 2851) 2852 2853(mat eqv-hashtable-cell 2854 (let () 2855 (define-record fribble (x)) 2856 (define random-object 2857 (lambda (x) 2858 (case (random 9) 2859 [(0) (cons 'a 3.4)] 2860 [(1) (vector 'c)] 2861 [(2) (string #\a #\b)] 2862 [(3) (make-fribble 'q)] 2863 [(4) (gensym)] 2864 [(5) (open-output-string)] 2865 [(6) (fxvector 15 55)] 2866 [(7) (lambda () x)] 2867 [else (box 'top)]))) 2868 (let ([ls1 (let f ([n 10000]) 2869 (if (fx= n 0) 2870 '() 2871 (cons 2872 (cons (random-object 4) (random-object 7)) 2873 (f (fx- n 1)))))] 2874 [ht (make-eqv-hashtable)] 2875 [wht (make-weak-eqv-hashtable)] 2876 [eht (make-ephemeron-eqv-hashtable)]) 2877 (let ([ls2 (map (lambda (a1) (hashtable-cell ht (car a1) (cdr a1))) ls1)] 2878 [ls3 (map (lambda (a1) (hashtable-cell wht (car a1) (cdr a1))) ls1)] 2879 [ls4 (map (lambda (a1) (hashtable-cell eht (car a1) (cdr a1))) ls1)]) 2880 (unless (andmap (lambda (a1 a2 a3 a4) 2881 (and (eqv? (car a1) (car a2)) 2882 (eqv? (car a2) (car a3)) 2883 (eqv? (car a2) (car a4)))) 2884 ls1 ls2 ls3 ls4) 2885 (errorf #f "keys are not eqv")) 2886 (unless (andmap (lambda (a1 a2 a3 a4) 2887 (and (eqv? (cdr a1) (cdr a2)) 2888 (eqv? (cdr a2) (cdr a3)) 2889 (eqv? (cdr a2) (cdr a4)))) 2890 ls1 ls2 ls3 ls4) 2891 (errorf #f "values are not eqv")) 2892 (for-each (lambda (a1) 2893 (let ([o (random-object 3)]) 2894 ;; Value refers to key: 2895 (hashtable-set! eht o (list o (car a1))))) 2896 ls1) 2897 (for-each 2898 (lambda (a1) 2899 (when (fx< (random 10) 5) 2900 (set-car! a1 #f))) 2901 ls1) 2902 (let loop ([i (min (expt (collect-generation-radix) (collect-maximum-generation)) 1000)]) 2903 (unless (fx= i 0) 2904 (collect) 2905 (unless (andmap (lambda (a2 a3 a4) (and (eqv? (car a2) (car a3)) (eqv? (car a2) (car a4)))) 2906 ls2 ls3 ls4) 2907 (errorf #f "a2/a3/a4 keys not eqv after collection")) 2908 (unless (and (andmap (lambda (a3) (not (bwp-object? (car a3)))) ls3) 2909 (andmap (lambda (a4) (not (bwp-object? (car a4)))) ls4)) 2910 (errorf #f "keys have been bwp'd")) 2911 (loop (fx- i 1)))) 2912 (for-each 2913 (lambda (a2) 2914 (hashtable-delete! ht (car a2)) 2915 (set-car! a2 #f)) 2916 ls2) 2917 (unless (and (equal? (hashtable-keys ht) '#()) 2918 (equal? (hashtable-values ht) '#()) 2919 (zero? (hashtable-size ht))) 2920 (errorf #f "ht has not been cleared out")) 2921 (let loop ([i (min (expt (collect-generation-radix) (collect-maximum-generation)) 1000)]) 2922 (unless (fx= i 0) 2923 (collect) 2924 (unless (andmap (lambda (a1 a3 a4) 2925 (or (not (car a1)) 2926 (and (eqv? (car a1) (car a3)) 2927 (eqv? (car a1) (car a4))))) 2928 ls1 ls3 ls4) 2929 (errorf #f "a1/a3/a4 keys not eqv after collection")) 2930 (loop (fx- i 1)))) 2931 (for-each 2932 (lambda (a1 a3 a4) 2933 (unless (or (car a1) 2934 (and (bwp-object? (car a3)) 2935 (bwp-object? (car a4)))) 2936 (errorf #f "~s has not been bwp'd I" (car a3)))) 2937 ls1 ls3 ls4) 2938 (for-each (lambda (a1) (set-car! a1 #f)) ls1) 2939 (collect (collect-maximum-generation)) 2940 (unless (and (andmap (lambda (a3) (bwp-object? (car a3))) ls3) 2941 (andmap (lambda (a4) (bwp-object? (car a4))) ls4)) 2942 (errorf #f "keys have not been bwp'd II")) 2943 (unless (and (equal? (hashtable-keys wht) '#()) 2944 (equal? (hashtable-values wht) '#()) 2945 (zero? (hashtable-size wht))) 2946 (errorf #f "wht has not been cleared out")) 2947 (unless (and (equal? (hashtable-keys eht) '#()) 2948 (equal? (hashtable-values eht) '#()) 2949 (zero? (hashtable-size eht))) 2950 (errorf #f "eht has not been cleared out")))) 2951 #t) 2952 ) 2953 2954(mat eqv-strange 2955 (begin 2956 (define $ht (make-eqv-hashtable)) 2957 (define $wht (make-weak-eqv-hashtable)) 2958 (define $eht (make-weak-eqv-hashtable)) 2959 (and (hashtable? $ht) 2960 (hashtable? $wht) 2961 (hashtable? $eht))) 2962 (eqv? (hashtable-set! $ht #f 75) (void)) 2963 (eqv? (hashtable-ref $ht #f 80) 75) 2964 (eqv? (hashtable-set! $wht #f 75) (void)) 2965 (eqv? (hashtable-ref $wht #f 80) 75) 2966 (eqv? (hashtable-set! $eht #f 75) (void)) 2967 (eqv? (hashtable-ref $eht #f 80) 75) 2968 (eqv? (hashtable-set! $ht #!bwp "hello") (void)) 2969 (equal? (hashtable-ref $ht #!bwp "goodbye") "hello") 2970 (eqv? (hashtable-set! $wht #!bwp "hello") (void)) 2971 (eqv? (hashtable-set! $eht #!bwp "hello") (void)) 2972 (and (member (hashtable-ref $wht #!bwp "goodbye") '("hello" "goodbye")) #t) 2973 (and (member (hashtable-ref $eht #!bwp "goodbye") '("hello" "goodbye")) #t) 2974 ; make sure that association isn't added before procedure is called 2975 (equal? 2976 (begin 2977 (hashtable-update! $ht 'cupie 2978 (lambda (x) (hashtable-ref $ht 'cupie (cons 'barbie x))) 2979 'doll) 2980 (hashtable-ref $ht 'cupie 'oops)) 2981 '(barbie . doll)) 2982 (equal? 2983 (begin 2984 (hashtable-update! $wht 'cupie 2985 (lambda (x) (hashtable-ref $wht 'cupie (cons 'barbie x))) 2986 'doll) 2987 (hashtable-ref $wht 'cupie 'oops)) 2988 '(barbie . doll)) 2989 (equal? 2990 (begin 2991 (hashtable-update! $eht 'cupie 2992 (lambda (x) (hashtable-ref $eht 'cupie (cons 'barbie x))) 2993 'doll) 2994 (hashtable-ref $eht 'cupie 'oops)) 2995 '(barbie . doll)) 2996) 2997 2998(mat eqv-hashtable-stress 2999 ; stress tests 3000 (let () ; nonweak 3001 (define pick 3002 (lambda (ls) 3003 (list-ref ls (random (length ls))))) 3004 (define ht (make-eqv-hashtable 4)) 3005 (let ([ls (remq '|| (oblist))] [n 50000]) 3006 (let f ([i 0] [keep '()] [drop '()]) 3007 (if (= i n) 3008 (and (= (hashtable-size ht) (- n (length drop))) 3009 (andmap (lambda (k) 3010 (string=? 3011 (symbol->string (hashtable-ref ht k #f)) 3012 (cond 3013 [(string? k) k] 3014 [(pair? k) (car k)] 3015 [(vector? k) (vector-ref k 0)]))) 3016 keep) 3017 (andmap (lambda (k) (eqv? (hashtable-ref ht k 'no) 'no)) 3018 drop)) 3019 (let* ([x (pick ls)] [s (string-copy (symbol->string x))]) 3020 (let ([k (case (pick '(string pair vector)) 3021 [(string) s] 3022 [(pair) (list s)] 3023 [(vector) (vector s)])]) 3024 (hashtable-set! ht k x) 3025 (let ([keep (if (= (modulo i 5) 0) (cons k keep) keep)]) 3026 (if (= (modulo i 17) 5) 3027 (let ([k (pick keep)]) 3028 (hashtable-delete! ht k) 3029 (let ([drop (cons k drop)]) 3030 (when (= (random 5) 3) 3031 (hashtable-delete! ht (pick drop))) 3032 (f (+ i 1) (remq k keep) drop))) 3033 (f (+ i 1) keep drop))))))))) 3034 3035 (let () ; weak 3036 (define pick 3037 (lambda (ls) 3038 (list-ref ls (random (length ls))))) 3039 (define ht (make-weak-eqv-hashtable 4)) 3040 (let ([ls (remq '|| (oblist))] [n 50000]) 3041 (let f ([i 0] [keep '()] [drop '()]) 3042 (if (= i n) 3043 (and (<= (hashtable-size ht) (- n (length drop))) 3044 (begin 3045 (collect (collect-maximum-generation)) 3046 (= (hashtable-size ht) (length keep))) 3047 (andmap (lambda (k) 3048 (string=? 3049 (symbol->string (hashtable-ref ht k #f)) 3050 (cond 3051 [(string? k) k] 3052 [(pair? k) (car k)] 3053 [(vector? k) (vector-ref k 0)]))) 3054 keep) 3055 (andmap (lambda (k) (eqv? (hashtable-ref ht k 'no) 'no)) 3056 drop)) 3057 (let* ([x (pick ls)] [s (string-copy (symbol->string x))]) 3058 (let ([k (case (pick '(string pair vector)) 3059 [(string) s] 3060 [(pair) (list s)] 3061 [(vector) (vector s)])]) 3062 (hashtable-set! ht k x) 3063 (let ([keep (if (= (modulo i 5) 0) (cons k keep) keep)]) 3064 (if (= (modulo i 17) 5) 3065 (let ([k (pick keep)]) 3066 (hashtable-delete! ht k) 3067 (let ([drop (cons k drop)]) 3068 (when (= (random 5) 3) 3069 (hashtable-delete! ht (pick drop))) 3070 (f (+ i 1) (remq k keep) drop))) 3071 (f (+ i 1) keep drop))))))))) 3072 3073 (let () ; ephemeron 3074 (define pick 3075 (lambda (ls) 3076 (list-ref ls (random (length ls))))) 3077 (define ht (make-ephemeron-eqv-hashtable 4)) 3078 (let ([ls (remq '|| (oblist))] [n 50000]) 3079 (let f ([i 0] [keep '()] [drop '()]) 3080 (if (= i n) 3081 (and (<= (hashtable-size ht) (- n (length drop))) 3082 (begin 3083 (collect (collect-maximum-generation)) 3084 (= (hashtable-size ht) (length keep))) 3085 (andmap (lambda (k) 3086 (string=? 3087 (symbol->string (hashtable-ref ht k #f)) 3088 (cond 3089 [(string? k) k] 3090 [(pair? k) (car k)] 3091 [(vector? k) (vector-ref k 0)]))) 3092 keep) 3093 (andmap (lambda (k) (eqv? (hashtable-ref ht k 'no) 'no)) 3094 drop)) 3095 (let* ([x (pick ls)] [s (string-copy (symbol->string x))]) 3096 (let ([k (case (pick '(string pair vector)) 3097 [(string) s] 3098 [(pair) (list s)] 3099 [(vector) (vector s)])]) 3100 (hashtable-set! ht k x) 3101 (let ([keep (if (= (modulo i 5) 0) (cons k keep) keep)]) 3102 (if (= (modulo i 17) 5) 3103 (let ([k (pick keep)]) 3104 (hashtable-delete! ht k) 3105 (let ([drop (cons k drop)]) 3106 (when (= (random 5) 3) 3107 (hashtable-delete! ht (pick drop))) 3108 (f (+ i 1) (remq k keep) drop))) 3109 (f (+ i 1) keep drop))))))))) 3110 3111) 3112 3113(mat symbol-hashtable 3114 (let ([ht (make-hashtable symbol-hash eq?)]) 3115 (and (symbol-hashtable? ht) (eq? (hashtable-equivalence-function ht) eq?))) 3116 (let ([ht (make-hashtable symbol-hash eqv?)]) 3117 (and (symbol-hashtable? ht) (eq? (hashtable-equivalence-function ht) eqv?))) 3118 (let ([ht (make-hashtable symbol-hash equal?)]) 3119 (and (symbol-hashtable? ht) (eq? (hashtable-equivalence-function ht) equal?))) 3120 (let ([ht (make-hashtable symbol-hash symbol=?)]) 3121 (and (symbol-hashtable? ht) (eq? (hashtable-equivalence-function ht) symbol=?))) 3122 (let ([ht (make-hashtable symbol-hash eq? 17)]) 3123 (and (symbol-hashtable? ht) (eq? (hashtable-equivalence-function ht) eq?))) 3124 (let ([ht (make-hashtable symbol-hash eqv? 17)]) 3125 (and (symbol-hashtable? ht) (eq? (hashtable-equivalence-function ht) eqv?))) 3126 (let ([ht (make-hashtable symbol-hash equal? 17)]) 3127 (and (symbol-hashtable? ht) (eq? (hashtable-equivalence-function ht) equal?))) 3128 (let ([ht (make-hashtable symbol-hash symbol=? 17)]) 3129 (and (symbol-hashtable? ht) (eq? (hashtable-equivalence-function ht) symbol=?))) 3130 (begin 3131 (define h (make-hashtable symbol-hash eq? 32)) 3132 (and (hashtable? h) 3133 (symbol-hashtable? h) 3134 (hashtable-mutable? h) 3135 (not (eq-hashtable? h)) 3136 (not (hashtable-weak? h)) 3137 (not (hashtable-ephemeron? h)))) 3138 (eq? (hashtable-hash-function h) symbol-hash) 3139 (eq? (hashtable-equivalence-function h) eq?) 3140 (equal? (hashtable-size h) 0) 3141 (equal-entries? h '#() '#()) 3142 (eqv? (hashtable-set! h 'a 'aval) (void)) 3143 (equal? 3144 (list 3145 (hashtable-contains? h 'a) 3146 (hashtable-contains? h 'b) 3147 (hashtable-contains? h 'c)) 3148 '(#t #f #f)) 3149 (eqv? (hashtable-set! h 'b 'bval) (void)) 3150 (equal? 3151 (list 3152 (hashtable-contains? h 'a) 3153 (hashtable-contains? h 'b) 3154 (hashtable-contains? h 'c)) 3155 '(#t #t #f)) 3156 (eqv? (hashtable-set! h 'c 'cval) (void)) 3157 (equal? 3158 (list 3159 (hashtable-contains? h 'a) 3160 (hashtable-contains? h 'b) 3161 (hashtable-contains? h 'c)) 3162 '(#t #t #t)) 3163 (equal? (hashtable-size h) 3) 3164 (equal-entries? h '#(b c a) '#(bval cval aval)) 3165 #;(same-elements? (list->vector (hashtable-map h cons)) '#((a . aval) (b . bval) (c . cval))) 3166 #;(same-elements? 3167 (let ([v (make-vector 3)] [i 0]) 3168 (hashtable-for-each h (lambda (key val) (vector-set! v i (cons key val)) (set! i (fx+ i 1)))) 3169 v) 3170 '#((a . aval) (b . bval) (c . cval))) 3171 #;(same-elements? 3172 (let ([v (make-vector 3)] [i 0]) 3173 (hashtable-for-each-cell h (lambda (a) (vector-set! v i a) (set! i (fx+ i 1)))) 3174 v) 3175 '#((a . aval) (b . bval) (c . cval))) 3176 (equal? (hashtable-ref h 'a 1) 'aval) 3177 (equal? (hashtable-ref h 'b #f) 'bval) 3178 (equal? (hashtable-ref h 'c 'nope) 'cval) 3179 (eqv? (hashtable-delete! h 'b) (void)) 3180 (equal? (hashtable-size h) 2) 3181 (equal-entries? h '#(a c) '#(aval cval)) 3182 (begin 3183 (define h2 (hashtable-copy h #t)) 3184 (and (hashtable? h2) 3185 (symbol-hashtable? h2) 3186 (hashtable-mutable? h2) 3187 (not (hashtable-weak? h2)) 3188 (not (hashtable-ephemeron? h2)) 3189 (not (eq-hashtable? h2)))) 3190 (eq? (hashtable-hash-function h2) symbol-hash) 3191 (eq? (hashtable-equivalence-function h2) eq?) 3192 (equal? (hashtable-size h2) 2) 3193 (equal-entries? h2 '#(a c) '#(aval cval)) 3194 (eqv? (hashtable-clear! h 4) (void)) 3195 (equal? 3196 (list 3197 (hashtable-size h) 3198 (hashtable-ref h 'a 1) 3199 (hashtable-ref h 'b #f) 3200 (hashtable-ref h 'c 'nope)) 3201 '(0 1 #f nope)) 3202 (equal-entries? h '#() '#()) 3203 (equal? 3204 (list 3205 (hashtable-size h2) 3206 (hashtable-ref h2 'a 1) 3207 (hashtable-ref h2 'b #f) 3208 (hashtable-ref h2 'c 'nope)) 3209 '(2 aval #f cval)) 3210 (equal-entries? h2 '#(a c) '#(aval cval)) 3211 (eqv? 3212 (hashtable-update! h 'q 3213 (lambda (x) (+ x 1)) 3214 17) 3215 (void)) 3216 (equal? (hashtable-ref h 'q #f) 18) 3217 (eqv? 3218 (hashtable-update! h 'q 3219 (lambda (x) (+ x 1)) 3220 17) 3221 (void)) 3222 (equal? (hashtable-ref h 'q #f) 19) 3223 (equal? (hashtable-size h) 1) 3224 ; test hashtable-copy when some keys may have moved 3225 ; symbol hashes don't change, but keeping test adapted from eq-hashtable mats anyway 3226 (let ([t (parameterize ([collect-request-handler void]) 3227 (let ([h4a (make-hashtable symbol-hash eqv? 32)] 3228 [k* (list-head (oblist) 100)]) 3229 (for-each (lambda (x) (hashtable-set! h4a x x)) k*) 3230 (collect) 3231 ; create copy after collection but before otherwise touching h4a 3232 (let ([h4b (hashtable-copy h4a #t)]) 3233 (andmap 3234 (lambda (k) (eq? (hashtable-ref h4b k #f) k)) 3235 k*))))]) 3236 (collect) 3237 t) 3238 ; test for proper shrinkage 3239 (eqv? 3240 (let ([ht (make-hashtable symbol-hash equal? 32)]) 3241 (for-each 3242 (lambda (k*) (for-each (lambda (k) (hashtable-delete! ht k)) k*)) 3243 (let ([k** (map (lambda (x) (list-head (oblist) 1000)) (make-list 100))]) 3244 (for-each 3245 (lambda (k*) (map (lambda (k) (hashtable-set! ht k 75)) k*)) 3246 k**) 3247 k**)) 3248 (#%$hashtable-veclen ht)) 3249 32) 3250) 3251 3252(mat $symbol-hashtable 3253 (begin 3254 (define h (make-hashtable symbol-hash eq? 32)) 3255 (and (hashtable? h) 3256 (symbol-hashtable? h) 3257 (hashtable-mutable? h) 3258 (not (eq-hashtable? h)) 3259 (not (hashtable-weak? h)) 3260 (not (hashtable-ephemeron? h)))) 3261 (eq? (hashtable-hash-function h) symbol-hash) 3262 (eq? (hashtable-equivalence-function h) eq?) 3263 (equal? (hashtable-size h) 0) 3264 (equal-entries? h '#() '#()) 3265 (eqv? (symbol-hashtable-set! h 'a 'aval) (void)) 3266 (equal? 3267 (list 3268 (symbol-hashtable-contains? h 'a) 3269 (symbol-hashtable-contains? h 'b) 3270 (symbol-hashtable-contains? h 'c)) 3271 '(#t #f #f)) 3272 (eqv? (symbol-hashtable-set! h 'b 'bval) (void)) 3273 (equal? 3274 (list 3275 (symbol-hashtable-contains? h 'a) 3276 (symbol-hashtable-contains? h 'b) 3277 (symbol-hashtable-contains? h 'c)) 3278 '(#t #t #f)) 3279 (eqv? (symbol-hashtable-set! h 'c 'cval) (void)) 3280 (equal? 3281 (list 3282 (symbol-hashtable-contains? h 'a) 3283 (symbol-hashtable-contains? h 'b) 3284 (symbol-hashtable-contains? h 'c)) 3285 '(#t #t #t)) 3286 (equal? (hashtable-size h) 3) 3287 (equal-entries? h '#(b c a) '#(bval cval aval)) 3288 #;(same-elements? (list->vector (hashtable-map h cons)) '#((a . aval) (b . bval) (c . cval))) 3289 #;(same-elements? 3290 (let ([v (make-vector 3)] [i 0]) 3291 (hashtable-for-each h (lambda (key val) (vector-set! v i (cons key val)) (set! i (fx+ i 1)))) 3292 v) 3293 '#((a . aval) (b . bval) (c . cval))) 3294 #;(same-elements? 3295 (let ([v (make-vector 3)] [i 0]) 3296 (hashtable-for-each-cell h (lambda (a) (vector-set! v i a) (set! i (fx+ i 1)))) 3297 v) 3298 '#((a . aval) (b . bval) (c . cval))) 3299 (equal? (symbol-hashtable-ref h 'a 1) 'aval) 3300 (equal? (symbol-hashtable-ref h 'b #f) 'bval) 3301 (equal? (symbol-hashtable-ref h 'c 'nope) 'cval) 3302 (eqv? (symbol-hashtable-delete! h 'b) (void)) 3303 (equal? (hashtable-size h) 2) 3304 (equal-entries? h '#(a c) '#(aval cval)) 3305 (begin 3306 (define h2 (hashtable-copy h #t)) 3307 (and (hashtable? h2) 3308 (symbol-hashtable? h2) 3309 (hashtable-mutable? h2) 3310 (not (hashtable-weak? h2)) 3311 (not (hashtable-ephemeron? h2)) 3312 (not (eq-hashtable? h2)))) 3313 (eq? (hashtable-hash-function h2) symbol-hash) 3314 (eq? (hashtable-equivalence-function h2) eq?) 3315 (equal? (hashtable-size h2) 2) 3316 (equal-entries? h2 '#(a c) '#(aval cval)) 3317 (eqv? (hashtable-clear! h 4) (void)) 3318 (equal? 3319 (list 3320 (hashtable-size h) 3321 (symbol-hashtable-ref h 'a 1) 3322 (symbol-hashtable-ref h 'b #f) 3323 (symbol-hashtable-ref h 'c 'nope)) 3324 '(0 1 #f nope)) 3325 (equal-entries? h '#() '#()) 3326 (equal? 3327 (list 3328 (hashtable-size h2) 3329 (symbol-hashtable-ref h2 'a 1) 3330 (symbol-hashtable-ref h2 'b #f) 3331 (symbol-hashtable-ref h2 'c 'nope)) 3332 '(2 aval #f cval)) 3333 (equal-entries? h2 '#(a c) '#(aval cval)) 3334 (eqv? 3335 (symbol-hashtable-update! h 'q 3336 (lambda (x) (+ x 1)) 3337 17) 3338 (void)) 3339 (equal? (symbol-hashtable-ref h 'q #f) 18) 3340 (eqv? 3341 (symbol-hashtable-update! h 'q 3342 (lambda (x) (+ x 1)) 3343 17) 3344 (void)) 3345 (equal? (symbol-hashtable-ref h 'q #f) 19) 3346 (equal? (hashtable-size h) 1) 3347 (let ([g (gensym)] [s "feisty"]) 3348 (let ([a (symbol-hashtable-cell h g s)]) 3349 (and (pair? a) 3350 (eq? (car a) g) 3351 (eq? (cdr a) s) 3352 (begin 3353 (hashtable-set! h g 'feisty) 3354 (eq? (cdr a) 'feisty)) 3355 (begin 3356 (set-cdr! a (list "feisty")) 3357 (equal? (hashtable-ref h g #f) '("feisty")))))) 3358 ; test hashtable-copy when some keys may have moved 3359 ; symbol hashes don't change, but keeping test adapted from eq-hashtable mats anyway 3360 (let ([t (parameterize ([collect-request-handler void]) 3361 (let ([h4a (make-hashtable symbol-hash eqv? 32)] 3362 [k* (list-head (oblist) 100)]) 3363 (for-each (lambda (x) (symbol-hashtable-set! h4a x x)) k*) 3364 (collect) 3365 ; create copy after collection but before otherwise touching h4a 3366 (let ([h4b (hashtable-copy h4a #t)]) 3367 (andmap 3368 (lambda (k) (eq? (symbol-hashtable-ref h4b k #f) k)) 3369 k*))))]) 3370 (collect) 3371 t) 3372 ; test for proper shrinkage 3373 (eqv? 3374 (let ([ht (make-hashtable symbol-hash equal? 32)]) 3375 (for-each 3376 (lambda (k*) (for-each (lambda (k) (symbol-hashtable-delete! ht k)) k*)) 3377 (let ([k** (map (lambda (x) (list-head (oblist) 1000)) (make-list 100))]) 3378 (for-each 3379 (lambda (k*) (map (lambda (k) (symbol-hashtable-set! ht k 75)) k*)) 3380 k**) 3381 k**)) 3382 (#%$hashtable-veclen ht)) 3383 32) 3384) 3385 3386(mat symbol-hashtable-stress 3387 ; stress tests 3388 (let () ; nonweak 3389 (define pick 3390 (lambda (ls) 3391 (list-ref ls (random (length ls))))) 3392 (define ht (make-hashtable symbol-hash eq? 4)) 3393 (let ([ls (remq '|| (oblist))] [n 50000]) 3394 (let f ([i 0] [keep '()] [drop '()]) 3395 (if (= i n) 3396 (and (= (hashtable-size ht) (- n (length drop))) 3397 (andmap (lambda (k) 3398 (string=? 3399 (symbol->string (hashtable-ref ht k #f)) 3400 (symbol->string k))) 3401 keep) 3402 (andmap (lambda (k) (eq? (hashtable-ref ht k 'no) 'no)) 3403 drop)) 3404 (let* ([x (pick ls)] [s (string-copy (symbol->string x))]) 3405 (let ([k (gensym s)]) 3406 (hashtable-set! ht k x) 3407 (let ([keep (if (= (modulo i 5) 0) (cons k keep) keep)]) 3408 (if (= (modulo i 17) 5) 3409 (let ([k (pick keep)]) 3410 (hashtable-delete! ht k) 3411 (let ([drop (cons k drop)]) 3412 (when (= (random 5) 3) 3413 (hashtable-delete! ht (pick drop))) 3414 (f (+ i 1) (remq k keep) drop))) 3415 (f (+ i 1) keep drop))))))))) 3416) 3417 3418(mat generic-hashtable 3419 (begin 3420 (define $ght-keys1 '#(a b c d e f g)) 3421 (define $ght-vals1 '#(1 3 5 7 9 11 13)) 3422 (define $ght (make-hashtable equal-hash equal? 8)) 3423 (vector-for-each 3424 (lambda (x i) (hashtable-set! $ght x i)) 3425 $ght-keys1 3426 $ght-vals1) 3427 (hashtable? $ght)) 3428 (not (eq-hashtable? $ght)) 3429 (eq? (hashtable-hash-function $ght) equal-hash) 3430 (eq? (hashtable-equivalence-function $ght) equal?) 3431 (eq? (hashtable-mutable? $ght) #t) 3432 (not (hashtable-weak? $ght)) 3433 (not (hashtable-ephemeron? $ght)) 3434 (eqv? (hashtable-size $ght) (vector-length $ght-keys1)) 3435 (eqv? (#%$hashtable-veclen $ght) 8) 3436 (equal-entries? $ght $ght-keys1 $ght-vals1) 3437 (begin 3438 (define $ght-keys2 '#((a . b) (1 . 2) 3/4 3.4 3.5 1e23 #e1e50 1+1i 3+3.2i -15 #e1e-50 #1=(a . #1#) (#2=(#2# b c)))) 3439 (define $ght-vals2 '#(a b c d e f g h i j k l m)) 3440 (vector-for-each 3441 (lambda (x i) (hashtable-set! $ght x i)) 3442 $ght-keys2 3443 $ght-vals2) 3444 (eq? (hashtable-size $ght) (+ (vector-length $ght-keys1) (vector-length $ght-keys2)))) 3445 (> (#%$hashtable-veclen $ght) 8) 3446 (equal-entries? $ght ($vector-append $ght-keys1 $ght-keys2) ($vector-append $ght-vals1 $ght-vals2)) 3447 #;(same-elements? 3448 (list->vector (hashtable-map $ght cons)) 3449 (vector-map cons ($vector-append $ght-keys1 $ght-keys2) ($vector-append $ght-vals1 $ght-vals2))) 3450 #;(same-elements? 3451 (let ([v (make-vector (+ (vector-length $ght-keys1) (vector-length $ght-keys2)))] [i 0]) 3452 (hashtable-for-each $ght (lambda (key val) (vector-set! v i (cons key val)) (set! i (fx+ i 1)))) 3453 v) 3454 (vector-map cons ($vector-append $ght-keys1 $ght-keys2) ($vector-append $ght-vals1 $ght-vals2))) 3455 #;(same-elements? 3456 (let ([v (make-vector (+ (vector-length $ght-keys1) (vector-length $ght-keys2)))] [i 0]) 3457 (hashtable-for-each-cell $ght (lambda (a) (vector-set! v i a) (set! i (fx+ i 1)))) 3458 v) 3459 (vector-map cons ($vector-append $ght-keys1 $ght-keys2) ($vector-append $ght-vals1 $ght-vals2))) 3460 ($vector-andmap 3461 (lambda (k v) (equal? (hashtable-ref $ght k #f) v)) 3462 $ght-keys1 3463 $ght-vals1) 3464 ($vector-andmap 3465 (lambda (k v) (equal? (hashtable-ref $ght k #f) v)) 3466 $ght-keys2 3467 $ght-vals2) 3468 ($vector-andmap 3469 (lambda (k v) (equal? (hashtable-ref $ght k #f) v)) 3470 '#((a . b) (1 . 2) 3/4 3.4 3.5 1e23 #e1e50 1+1i 3+3.2i -15 #e1e-50 #3=(a . #3#) (#4=(#4# b c))) 3471 $ght-vals2) 3472 ($vector-andmap 3473 (lambda (k) (hashtable-contains? $ght k)) 3474 $ght-keys1) 3475 ($vector-andmap 3476 (lambda (k) (hashtable-contains? $ght k)) 3477 $ght-keys2) 3478 (not (hashtable-contains? $ght '(not a key))) 3479 (eq? (hashtable-ref $ght '(not a key) 'not-a-key) 'not-a-key) 3480 (begin 3481 (define $ght2 (hashtable-copy $ght)) 3482 (and (hashtable? $ght2) 3483 (not (hashtable-mutable? $ght2)) 3484 (not (hashtable-weak? $ght2)) 3485 (not (hashtable-ephemeron? $ght2)))) 3486 (eq? (hashtable-hash-function $ght) equal-hash) 3487 (eq? (hashtable-equivalence-function $ght) equal?) 3488 (begin 3489 (define $ght3 (hashtable-copy $ght #t)) 3490 (and (hashtable? $ght3) 3491 (hashtable-mutable? $ght3) 3492 (not (hashtable-weak? $ght3)) 3493 (not (hashtable-ephemeron? $ght3)))) 3494 (eq? (hashtable-hash-function $ght) equal-hash) 3495 (eq? (hashtable-equivalence-function $ght) equal?) 3496 (begin 3497 (vector-for-each 3498 (lambda (k) (hashtable-delete! $ght k)) 3499 $ght-keys1) 3500 #t) 3501 (equal-entries? $ght $ght-keys2 $ght-vals2) 3502 (eqv? (hashtable-size $ght) (vector-length $ght-keys2)) 3503 (begin 3504 (vector-for-each 3505 (lambda (k) (hashtable-delete! $ght k)) 3506 $ght-keys2) 3507 #t) 3508 (equal-entries? $ght '#() '#()) 3509 (eqv? (hashtable-size $ght) 0) 3510 (eqv? (#%$hashtable-veclen $ght) 8) 3511 ; make sure copies are unaffected by deletions 3512 (eq? (hashtable-size $ght2) (+ (vector-length $ght-keys1) (vector-length $ght-keys2))) 3513 (equal-entries? $ght2 ($vector-append $ght-keys1 $ght-keys2) ($vector-append $ght-vals1 $ght-vals2)) 3514 (eq? (hashtable-size $ght3) (+ (vector-length $ght-keys1) (vector-length $ght-keys2))) 3515 (equal-entries? $ght3 ($vector-append $ght-keys1 $ght-keys2) ($vector-append $ght-vals1 $ght-vals2)) 3516 (begin 3517 (hashtable-clear! $ght3) 3518 (and 3519 (eqv? (hashtable-size $ght3) 0) 3520 (eqv? (hashtable-size $ght2) (+ (vector-length $ght-keys1) (vector-length $ght-keys2))))) 3521 (error? ; not mutable 3522 (hashtable-clear! $ght2)) 3523 (error? ; not mutable 3524 (hashtable-delete! $ght2 (vector-ref $ght-keys2 0))) 3525 (error? ; not mutable 3526 (hashtable-update! $ght2 (vector-ref $ght-keys2 0) 3527 (lambda (x) (cons x x)) 3528 'oops)) 3529 (error? ; not mutable 3530 (hashtable-update! $ght2 '(not a key) 3531 (lambda (x) (cons x x)) 3532 'oops)) 3533 (eqv? 3534 (hashtable-update! $ght3 '(a . b) 3535 (lambda (x) (+ x 15)) 3536 17) 3537 (void)) 3538 (eqv? 3539 (hashtable-update! $ght3 '(a . b) 3540 (lambda (x) (+ x 29)) 3541 17) 3542 (void)) 3543 (eqv? 3544 (hashtable-update! $ght3 1e23 3545 (lambda (x) (- x 5)) 3546 19) 3547 (void)) 3548 (equal? 3549 (let ([a (hashtable-cell $ght3 '(a . b) 17)]) 3550 (set-cdr! a (+ (cdr a) 100)) 3551 a) 3552 '((a . b) . 161)) 3553 (equal? 3554 (let ([a (hashtable-cell $ght3 #vu8(1 2 3) 'bv)]) 3555 (set-cdr! a (cons (cdr a) 'vb)) 3556 a) 3557 '(#vu8(1 2 3) . (bv . vb))) 3558 (equal-entries? $ght3 '#((a . b) 1e23 #vu8(1 2 3)) '#(161 14 (bv . vb))) 3559 (let () ; carl's test program, with a few additions 3560 (define cov:prof-hash 3561 (lambda (V) 3562 (* (vector-ref V 0) (vector-ref V 1) (vector-ref V 2)))) 3563 (define cov:prof-equal? 3564 (lambda (V W) 3565 (let ((rv (and (= (vector-ref V 0) (vector-ref W 0)) 3566 (= (vector-ref V 1) (vector-ref W 1)) 3567 (= (vector-ref V 2) (vector-ref W 2))))) 3568 rv))) 3569 (define make-random-vector-key 3570 (lambda () 3571 (vector (random 20000) (random 100) (random 1000)))) 3572 (define test-hash 3573 (lambda (n) 3574 (let ([ht (make-hashtable cov:prof-hash cov:prof-equal?)]) 3575 (let loop ([i 0]) 3576 (let ([str (make-random-vector-key)]) 3577 (hashtable-set! ht str i) 3578 (hashtable-update! ht str (lambda (x) (* x 2)) -1) 3579 (let ([a (hashtable-cell ht str 'a)]) (set-cdr! a (- (cdr a)))) 3580 (cond 3581 [(= i n) (= (hashtable-size ht) 1000)] 3582 [(and (hashtable-contains? ht str) 3583 (= (hashtable-ref ht str #f) (* i -2))) 3584 (when (= (hashtable-size ht) 1000) 3585 (hashtable-delete! ht str)) 3586 (loop (+ i 1))] 3587 [else (errorf 'test-hash "hashtable failure for key ~s" str)])))))) 3588 (test-hash 100000)) 3589) 3590 3591(mat hash-functions 3592 ; equal-hash 3593 (error? ; wrong argument count 3594 (equal-hash)) 3595 (error? ; wrong argument count 3596 (equal-hash 0 0)) 3597 ; symbol-hash 3598 (error? ; wrong argument count 3599 (symbol-hash)) 3600 (error? ; wrong argument count 3601 (symbol-hash 'a 'a)) 3602 (error? ; not a symbol 3603 (symbol-hash "hello")) 3604 ; string-hash 3605 (error? ; wrong argument count 3606 (string-hash)) 3607 (error? ; wrong argument count 3608 (string-hash 'a 'a)) 3609 (error? ; not a string 3610 (string-hash 'hello)) 3611 ; string-ci-hash 3612 (error? ; wrong argument count 3613 (string-ci-hash)) 3614 (error? ; wrong argument count 3615 (string-ci-hash 'a 'a)) 3616 (error? ; not a string 3617 (string-ci-hash 'hello)) 3618 (let ([hc (equal-hash '(a b c))]) 3619 (and (integer? hc) 3620 (exact? hc) 3621 (>= hc 0) 3622 (= (equal-hash '(a b c)) hc))) 3623 (let ([hc (string-hash "hello")]) 3624 (and (integer? hc) 3625 (exact? hc) 3626 (>= hc 0) 3627 (= (string-hash "hello") hc))) 3628 (let ([hc (string-ci-hash "hello")]) 3629 (and (integer? hc) 3630 (exact? hc) 3631 (>= hc 0) 3632 (= (string-ci-hash "HelLo") hc))) 3633 (let f ([ls (oblist)]) 3634 (define okay? 3635 (lambda (x) 3636 (let ([hc (symbol-hash x)]) 3637 (and (integer? hc) 3638 (exact? hc) 3639 (>= hc 0) 3640 (= (symbol-hash x) hc))))) 3641 (and (okay? (car ls)) 3642 (let g ([ls ls] [n 10]) 3643 (or (null? ls) 3644 (if (= n 0) 3645 (f ls) 3646 (g (cdr ls) (- n 1))))))) 3647 ; adapted from Flatt's r6rs tests for string-ci=? 3648 (eqv? (string-ci-hash "z") (string-ci-hash "Z")) 3649 (not (eqv? (string-ci-hash "z") (string-ci-hash "a"))) 3650 (eqv? (string-ci-hash "Stra\xDF;e") (string-ci-hash "Strasse")) 3651 (eqv? (string-ci-hash "Stra\xDF;e") (string-ci-hash "STRASSE")) 3652 (eqv? (string-ci-hash "\x39E;\x391;\x39F;\x3A3;") (string-ci-hash "\x3BE;\x3B1;\x3BF;\x3C2;")) 3653 (eqv? (string-ci-hash "\x39E;\x391;\x39F;\x3A3;") (string-ci-hash "\x3BE;\x3B1;\x3BF;\x3C3;")) 3654) 3655 3656(mat fasl-eq-hashtable 3657 ; fasling out eq hash tables 3658 (equal? 3659 (let ([x (cons 'y '!)]) 3660 (define ht (make-eq-hashtable)) 3661 (eq-hashtable-set! ht x 'because) 3662 (eq-hashtable-set! ht 'foo "foo") 3663 (let ([p (open-file-output-port "testfile.ss" (file-options replace))]) 3664 (fasl-write (list x ht) p) 3665 (close-port p)) 3666 (let-values ([(x2 ht2) 3667 (apply values 3668 (call-with-port 3669 (open-file-input-port "testfile.ss") 3670 fasl-read))]) 3671 (list 3672 (eq-hashtable-weak? ht2) 3673 (eq-hashtable-ephemeron? ht2) 3674 (eq-hashtable-ref ht2 x2 #f) 3675 (eq-hashtable-ref ht2 'foo #f)))) 3676 '(#f #f because "foo")) 3677 ; fasling out weak eq hash table 3678 (equal? 3679 (with-interrupts-disabled 3680 (let ([x (cons 'y '!)]) 3681 (define ht (make-weak-eq-hashtable)) 3682 (eq-hashtable-set! ht x 'because) 3683 (eq-hashtable-set! ht 'foo "foo") 3684 (let ([p (open-file-output-port "testfile.ss" (file-options replace))]) 3685 (fasl-write (list x ht) p) 3686 (close-port p)) 3687 (let-values ([(x2 ht2) 3688 (apply values 3689 (call-with-port 3690 (open-file-input-port "testfile.ss") 3691 fasl-read))]) 3692 (list 3693 (eq-hashtable-weak? ht2) 3694 (eq-hashtable-ephemeron? ht2) 3695 (eq-hashtable-ref ht2 x2 #f) 3696 (eq-hashtable-ref ht2 'foo #f))))) 3697 '(#t #f because "foo")) 3698 (equal? 3699 (let ([ht2 (cadr (call-with-port 3700 (open-file-input-port "testfile.ss") 3701 fasl-read))]) 3702 (collect (collect-maximum-generation)) 3703 (list 3704 (hashtable-keys ht2) 3705 (eq-hashtable-ref ht2 'foo #f))) 3706 '(#(foo) "foo")) 3707 ; fasling out ephemeron eq hash table 3708 (equal? 3709 (with-interrupts-disabled 3710 (let ([x (cons 'y '!)]) 3711 (define ht (make-ephemeron-eq-hashtable)) 3712 (eq-hashtable-set! ht x 'because) 3713 (eq-hashtable-set! ht 'foo "foo") 3714 (let ([p (open-file-output-port "testfile.ss" (file-options replace))]) 3715 (fasl-write (list x ht) p) 3716 (close-port p)) 3717 (let-values ([(x2 ht2) 3718 (apply values 3719 (call-with-port 3720 (open-file-input-port "testfile.ss") 3721 fasl-read))]) 3722 (list 3723 (eq-hashtable-weak? ht2) 3724 (eq-hashtable-ephemeron? ht2) 3725 (eq-hashtable-ref ht2 x2 #f) 3726 (eq-hashtable-ref ht2 'foo #f))))) 3727 '(#f #t because "foo")) 3728 (equal? 3729 (let ([ht2 (cadr (call-with-port 3730 (open-file-input-port "testfile.ss") 3731 fasl-read))]) 3732 (collect (collect-maximum-generation)) 3733 (list 3734 (hashtable-keys ht2) 3735 (eq-hashtable-ref ht2 'foo #f))) 3736 '(#(foo) "foo")) 3737 ; fasling eq hash tables via compile-file 3738 (begin 3739 (with-output-to-file "testfile.ss" 3740 (lambda () 3741 (pretty-print 3742 '(module ($feh-ls $feh-ht) 3743 (define-syntax ls 3744 (let ([ls '(1 2 3)]) 3745 (lambda (x) 3746 #`(quote #,(datum->syntax #'* ls))))) 3747 (define $feh-ls ls) 3748 (define $feh-ht 3749 (let () 3750 (define-syntax a 3751 (let ([ht (make-eq-hashtable)]) 3752 (eq-hashtable-set! ht 'q 'p) 3753 (eq-hashtable-set! ht ls (cdr ls)) 3754 (eq-hashtable-set! ht (cdr ls) (cddr ls)) 3755 (eq-hashtable-set! ht (cddr ls) ls) 3756 (lambda (x) #`(quote #,(datum->syntax #'* ht))))) 3757 a))))) 3758 'replace) 3759 (compile-file "testfile") 3760 (load "testfile.so") 3761 #t) 3762 (eq? (eq-hashtable-ref $feh-ht 'q #f) 'p) 3763 (eq? (eq-hashtable-ref $feh-ht $feh-ls #f) (cdr $feh-ls)) 3764 (eq? (eq-hashtable-ref $feh-ht (cdr $feh-ls) #f) (cddr $feh-ls)) 3765 (eq? (eq-hashtable-ref $feh-ht (cddr $feh-ls) #f) $feh-ls) 3766 (begin 3767 (eq-hashtable-set! $feh-ht 'p 'r) 3768 #t) 3769 (eq? (eq-hashtable-ref $feh-ht 'p #f) 'r) 3770 (begin 3771 (eq-hashtable-set! $feh-ht 'q 'not-p) 3772 #t) 3773 (eq? (eq-hashtable-ref $feh-ht 'q #f) 'not-p) 3774) 3775 3776(mat fasl-symbol-hashtable 3777 ; fasling out symbol hash tables 3778 (equal? 3779 (let () 3780 (define ht (make-hashtable symbol-hash eq?)) 3781 (symbol-hashtable-set! ht 'why? 'because) 3782 (symbol-hashtable-set! ht 'foo "foo") 3783 (let ([p (open-file-output-port "testfile.ss" (file-options replace))]) 3784 (fasl-write ht p) 3785 (close-port p)) 3786 (let ([ht2 (call-with-port (open-file-input-port "testfile.ss") fasl-read)]) 3787 (list 3788 (symbol-hashtable-ref ht2 'why? #f) 3789 (symbol-hashtable-ref ht2 'foo #f)))) 3790 '(because "foo")) 3791 (#%$fasl-file-equal? "testfile.ss" "testfile.ss") 3792 (eqv? (strip-fasl-file "testfile.ss" "testfile1.ss" (fasl-strip-options)) (void)) 3793 (#%$fasl-file-equal? "testfile.ss" "testfile1.ss") 3794 (equal? 3795 (let ([ht2 (call-with-port (open-file-input-port "testfile1.ss" (file-options compressed)) fasl-read)]) 3796 (list 3797 (symbol-hashtable-ref ht2 'why? #f) 3798 (symbol-hashtable-ref ht2 'foo #f))) 3799 '(because "foo")) 3800 (begin 3801 (call-with-port (open-file-output-port "testfile1.ss" (file-options replace)) 3802 (lambda (p) 3803 (fasl-write (call-with-port (open-file-input-port "testfile.ss") fasl-read) p))) 3804 #t) 3805 (#%$fasl-file-equal? "testfile.ss" "testfile1.ss") 3806 (#%$fasl-file-equal? "testfile1.ss" "testfile.ss") 3807 (begin 3808 (call-with-port (open-file-output-port "testfile1.ss" (file-options replace)) 3809 (lambda (p) 3810 (let ([ht (call-with-port (open-file-input-port "testfile.ss") fasl-read)]) 3811 (symbol-hashtable-set! ht 'why? 'why-not?) 3812 (fasl-write ht p)))) 3813 #t) 3814 (not (#%$fasl-file-equal? "testfile.ss" "testfile1.ss")) 3815 (not (#%$fasl-file-equal? "testfile1.ss" "testfile.ss")) 3816 (begin 3817 (call-with-port (open-file-output-port "testfile1.ss" (file-options replace)) 3818 (lambda (p) 3819 (let ([ht (call-with-port (open-file-input-port "testfile.ss") fasl-read)]) 3820 (symbol-hashtable-set! ht (gensym) 'foiled) 3821 (fasl-write ht p)))) 3822 #t) 3823 (not (#%$fasl-file-equal? "testfile.ss" "testfile1.ss")) 3824 (not (#%$fasl-file-equal? "testfile1.ss" "testfile.ss")) 3825 3826 ; fasling symbol hash tables via compile-file 3827 (begin 3828 (with-output-to-file "testfile.ss" 3829 (lambda () 3830 (pretty-print 3831 '(define $fsh-ht 3832 (let () 3833 (define-syntax a 3834 (let ([ht (make-hashtable symbol-hash symbol=?)]) 3835 (symbol-hashtable-set! ht 'q 'p) 3836 (symbol-hashtable-set! ht 'p 's) 3837 (let ([g (gensym "hello")]) 3838 (symbol-hashtable-set! ht g g) 3839 (symbol-hashtable-set! ht 'g g)) 3840 (lambda (x) #`(quote #,(datum->syntax #'* ht))))) 3841 a)))) 3842 'replace) 3843 (compile-file "testfile") 3844 (load "testfile.so") 3845 #t) 3846 (eq? (symbol-hashtable-ref $fsh-ht 'q #f) 'p) 3847 (eq? (symbol-hashtable-ref $fsh-ht 'p #f) 's) 3848 (let ([g (symbol-hashtable-ref $fsh-ht 'g #f)]) 3849 (eq? (symbol-hashtable-ref $fsh-ht g #f) g)) 3850 (eq? (symbol-hashtable-ref $fsh-ht 'spam #f) #f) 3851 (begin 3852 (symbol-hashtable-set! $fsh-ht 'p 'r) 3853 #t) 3854 (eq? (symbol-hashtable-ref $fsh-ht 'p #f) 'r) 3855 (begin 3856 (symbol-hashtable-set! $fsh-ht 'q 'not-p) 3857 #t) 3858 (eq? (symbol-hashtable-ref $fsh-ht 'q #f) 'not-p) 3859) 3860 3861(mat fasl-other-hashtable 3862 ; can't fasl out other kinds of hashtables 3863 (error? 3864 (let ([x (cons 'y '!)]) 3865 (define ht (make-eqv-hashtable)) 3866 (hashtable-set! ht x 'because) 3867 (hashtable-set! ht 'foo "foo") 3868 (hashtable-set! ht 3.1415 "pi") 3869 (let ([p (open-file-output-port "testfile.ss" (file-options replace))]) 3870 (with-exception-handler 3871 (lambda (c) (close-port p) (raise-continuable c)) 3872 (lambda () (fasl-write (list x ht) p)))))) 3873 (error? 3874 (let ([x (cons 'y '!)]) 3875 (define ht (make-hashtable string-hash string=?)) 3876 (hashtable-set! ht "hello" 'goodbye) 3877 (let ([p (open-file-output-port "testfile.ss" (file-options replace))]) 3878 (with-exception-handler 3879 (lambda (c) (close-port p) (raise-continuable c)) 3880 (lambda () (fasl-write (list x ht) p)))))) 3881) 3882 3883(mat ht 3884 (begin 3885 (display-string (separate-eval '(parameterize ([source-directories '("." "../s" "../../s")]) (load "ht.ss")))) 3886 #t) 3887) 3888