@@ -353,211 +353,6 @@ mod chained {
353
353
}
354
354
}
355
355
356
- /*
357
- Function: mk_flat_hashmap
358
-
359
- Construct a "flat" hashmap, meaning that there are
360
- not chains per buckets, but rather we search a sequence
361
- of buckets for each key.
362
-
363
- Warning: it is unclear to me that this code is correct
364
- on 32-bit processors. Check out the 'hash-tearing' code
365
- in hash() and the comment surrounding it. - Niko
366
-
367
- Parameters:
368
-
369
- hasher - The hash function for key type K
370
- eqer - The equality function for key type K
371
- */
372
- fn mk_flat_hashmap < copy K , copy V > ( hasher : hashfn < K > , eqer : eqfn < K > )
373
- -> hashmap < K , V > {
374
- let initial_capacity: uint = 32 u; // 2^5
375
-
376
- let load_factor: util:: rational = { num: 3 , den: 4 } ;
377
- tag bucket<copy K , copy V > { nil; deleted; some ( K , V ) ; }
378
- fn make_buckets < copy K , copy V > ( nbkts : uint ) -> [ mutable bucket< K , V > ] {
379
- ret vec:: init_elt_mut :: < bucket < K , V > > ( nil :: < K , V > , nbkts) ;
380
- }
381
- // Derive two hash functions from the one given by taking the upper
382
- // half and lower half of the uint bits. Our bucket probing
383
- // sequence is then defined by
384
- //
385
- // hash(key, i) := hashl(key) * i + hashr(key) for i = 0, 1, 2, ...
386
- //
387
- // Tearing the hash function apart this way is kosher in practice
388
- // as, assuming 32-bit uints, the table would have to be at 2^32
389
- // buckets before the resulting pair of hash functions no longer
390
- // probes all buckets for a fixed key. Note that hashl is made to
391
- // output odd numbers (hence coprime to the number of nbkts, which
392
- // is always a power? of 2), so that all buckets are probed for a
393
- // fixed key.
394
-
395
- fn hashl ( n : uint ) -> uint { ret ( n >>> 16 u) * 2 u + 1 u; }
396
- fn hashr ( n : uint ) -> uint { ret 0x0000_ffff_ u & n; }
397
- fn hash ( h : uint , nbkts : uint , i : uint ) -> uint {
398
- ret ( hashl ( h) * i + hashr ( h) ) % nbkts;
399
- }
400
-
401
- /**
402
- * We attempt to never call this with a full table. If we do, it
403
- * will fail.
404
- */
405
- fn insert_common < copy K , copy V > ( hasher : hashfn < K > , eqer : eqfn < K > ,
406
- bkts : [ mutable bucket< K , V > ] ,
407
- nbkts : uint , key : K , val : V ) -> bool {
408
- let i: uint = 0 u;
409
- let h = hasher ( key) ;
410
- while i < nbkts {
411
- let j: uint = hash ( h, nbkts, i) ;
412
- alt bkts[ j] {
413
- some ( k, _) {
414
- // Copy key to please alias analysis.
415
-
416
- let k_ = k;
417
- if eqer ( key, k_) {
418
- log ( "map updated" , "i" , i, "h" , h, "nbkts" , nbkts) ;
419
- bkts[ j] = some ( k_, val) ;
420
- ret false;
421
- }
422
- i += 1 u;
423
- }
424
- _ {
425
- log( "map inserted" , "i" , i, "h" , h, "nbkts" , nbkts) ;
426
- bkts[ j] = some ( key, val) ;
427
- ret true;
428
- }
429
- }
430
- }
431
- fail; // full table
432
- }
433
- fn find_common < copy K , copy V > ( hasher : hashfn < K > , eqer : eqfn < K > ,
434
- bkts : [ mutable bucket< K , V > ] ,
435
- nbkts : uint , key : K ) -> option:: t < V > {
436
- let i: uint = 0 u;
437
- let h = hasher ( key) ;
438
- while i < nbkts {
439
- let j: uint = hash ( h, nbkts, i) ;
440
- alt bkts[ j] {
441
- some ( k, v) {
442
- // Copy to please alias analysis.
443
- let k_ = k;
444
- let v_ = v;
445
- if eqer ( key, k_) {
446
- log ( "map present" , "i" , i, "h" , h, "nbkts" , nbkts) ;
447
- ret option:: some ( v_) ;
448
- }
449
- }
450
- nil. {
451
- log ( "map absent" , "i" , i, "h" , h, "nbkts" , nbkts) ;
452
- ret option:: none;
453
- }
454
- deleted. { }
455
- }
456
- i += 1 u;
457
- }
458
- ret option:: none;
459
- }
460
- fn rehash < copy K , copy V > ( hasher : hashfn < K > , eqer : eqfn < K > ,
461
- oldbkts : [ mutable bucket< K , V > ] ,
462
- _noldbkts : uint ,
463
- newbkts : [ mutable bucket< K , V > ] ,
464
- nnewbkts : uint ) {
465
- for b: bucket < K , V > in oldbkts {
466
- alt b {
467
- some( k_, v_) {
468
- let k = k_;
469
- let v = v_;
470
- insert_common( hasher, eqer, newbkts, nnewbkts, k, v) ;
471
- }
472
- _ { }
473
- }
474
- }
475
- }
476
- obj hashmap<copy K , copy V >( hasher: hashfn<K >,
477
- eqer: eqfn<K >,
478
- mutable bkts: [ mutable bucket<K , V >] ,
479
- mutable nbkts: uint,
480
- mutable nelts: uint,
481
- lf: util:: rational) {
482
- fn size ( ) -> uint { ret nelts; }
483
- fn insert ( key : K , val : V ) -> bool {
484
- let load: util:: rational =
485
- { num: nelts + 1 u as int , den: nbkts as int } ;
486
- if !util:: rational_leq ( load, lf) {
487
- let nnewbkts: uint = uint:: next_power_of_two ( nbkts + 1 u) ;
488
- let newbkts = make_buckets ( nnewbkts) ;
489
- rehash ( hasher, eqer, bkts, nbkts, newbkts, nnewbkts) ;
490
- bkts = newbkts;
491
- nbkts = nnewbkts;
492
- }
493
- if insert_common ( hasher, eqer, bkts, nbkts, key, val) {
494
- nelts += 1 u;
495
- ret true;
496
- }
497
- ret false;
498
- }
499
- fn contains_key ( key : K ) -> bool {
500
- ret alt find_common ( hasher, eqer, bkts, nbkts, key) {
501
- option:: some ( _) { true }
502
- _ { false }
503
- } ;
504
- }
505
- fn get ( key : K ) -> V {
506
- ret alt find_common ( hasher, eqer, bkts, nbkts, key) {
507
- option:: some ( val) { val }
508
- _ { fail }
509
- } ;
510
- }
511
- fn find ( key : K ) -> option:: t < V > {
512
- be find_common ( hasher, eqer, bkts, nbkts, key) ;
513
- }
514
- fn remove ( key : K ) -> option:: t < V > {
515
- let i: uint = 0 u;
516
- let h = hasher ( key) ;
517
- while i < nbkts {
518
- let j: uint = hash ( h, nbkts, i) ;
519
- alt bkts[ j] {
520
- some ( k, v) {
521
- let k_ = k;
522
- let vo = option:: some ( v) ;
523
- if eqer ( key, k_) {
524
- bkts[ j] = deleted;
525
- nelts -= 1 u;
526
- ret vo;
527
- }
528
- }
529
- deleted. { }
530
- nil . { ret option :: none; }
531
- }
532
- i += 1 u;
533
- }
534
- ret option:: none;
535
- }
536
- fn rehash ( ) {
537
- let newbkts = make_buckets ( nbkts) ;
538
- rehash ( hasher, eqer, bkts, nbkts, newbkts, nbkts) ;
539
- bkts = newbkts;
540
- }
541
- fn items ( it : block ( K , V ) ) {
542
- for b in bkts {
543
- alt b { some( k, v) { it ( copy k, copy v) ; } _ { } }
544
- }
545
- }
546
- fn keys ( it : block ( K ) ) {
547
- for b in bkts {
548
- alt b { some( k, _) { it ( copy k) ; } _ { } }
549
- }
550
- }
551
- fn values ( it : block ( V ) ) {
552
- for b in bkts {
553
- alt b { some( _, v) { it ( copy v) ; } _ { } }
554
- }
555
- }
556
- }
557
- let bkts = make_buckets ( initial_capacity) ;
558
- ret hashmap( hasher, eqer, bkts, initial_capacity, 0 u, load_factor) ;
559
- }
560
-
561
356
/*
562
357
Function: mk_hashmap
563
358
0 commit comments