377 I.e. this is the same as self at:aKey put:(aBlock value:(self at:aKey ifAbsent:default)). |
378 I.e. this is the same as self at:aKey put:(aBlock value:(self at:aKey ifAbsent:default)). |
378 Return the new value stored. |
379 Return the new value stored. |
379 This is an optimized accessor, which only computes the hash value once." |
380 This is an optimized accessor, which only computes the hash value once." |
380 |
381 |
381 |k index "{ Class: SmallInteger }" |
382 |k index "{ Class: SmallInteger }" |
382 newValue| |
383 newValue oldKeyArray oldKey| |
383 |
384 |
384 (k := aKey) isNil ifTrue:[ |
385 (k := aKey) isNil ifTrue:[ |
385 k := NilEntry |
386 k := NilEntry |
386 ]. |
387 ]. |
387 |
388 |
388 index := self findKeyOrNil:k. |
389 oldKeyArray := keyArray. |
389 (keyArray basicAt:index) notNil ifTrue:[ |
390 index := self findKeyOrNilOrDeletedEntry:k. |
390 "/ key present |
391 oldKey := keyArray basicAt:index. |
391 valueArray basicAt:index put:(newValue := aBlock value:(valueArray basicAt:index)). |
392 (oldKey notNil and:[oldKey ~~ DeletedEntry]) ifTrue:[ |
392 ^ newValue |
393 "/ key is present |
393 ]. |
394 newValue := aBlock value:(valueArray basicAt:index). |
394 "/ a new key |
395 ] ifFalse:[ |
395 keyArray basicAt:index put:k. |
396 "/ a new key |
396 valueArray basicAt:index put:(newValue := aBlock value:default). |
397 newValue := aBlock value:default. |
397 tally := tally + 1. |
398 ]. |
398 |
399 (keyArray ~~ oldKeyArray or:[(keyArray basicAt:index) ~~ oldKey]) ifTrue:[ |
399 self possiblyGrow. |
400 "I have been changed while performing aBlock. |
|
401 have to find the key again." |
|
402 index := self findKeyOrNil:k. |
|
403 ]. |
|
404 |
|
405 valueArray basicAt:index put:newValue. |
|
406 oldKey := keyArray basicAt:index. |
|
407 (oldKey isNil or:[oldKey == DeletedEntry]) ifTrue:[ |
|
408 "key is not or no longer present" |
|
409 keyArray basicAt:index put:k. |
|
410 tally := tally + 1. |
|
411 self possiblyGrow. |
|
412 ]. |
|
413 |
400 ^ newValue |
414 ^ newValue |
401 |
415 |
402 " |
416 " |
403 |d| |
417 |d| |
404 |
418 |
405 d := Dictionary new. |
419 d := Dictionary new. |
406 d at:'one' ifAbsent:0 update:[:val | val + 1]. |
420 d at:'one' ifAbsent:0 update:[:val | val + 1]. |
407 d at:'two' ifAbsent:0 update:[:val | val + 1]. |
421 d at:'two' ifAbsent:0 update:[:val | val + 1]. |
408 d at:'three' ifAbsent:0 update:[:val | val + 1]. |
422 d at:'three' ifAbsent:0 update:[:val | val + 1]. |
409 d at:'one' ifAbsent:0 update:[:val | val + 1]. |
|
410 d at:'two' ifAbsent:0 update:[:val | val + 1]. |
423 d at:'two' ifAbsent:0 update:[:val | val + 1]. |
|
424 d at:'three' ifAbsent:0 update:[:val | val + 1]. |
|
425 d at:'three' ifAbsent:0 update:[:val | val + 1]. |
|
426 d |
|
427 " |
|
428 |
|
429 " |
|
430 |d| |
|
431 |
|
432 d := Dictionary new. |
|
433 d at:'two' ifAbsent:0 update:[:val | val + 1]. |
|
434 d at:'two' ifAbsent:0 update:[:val | 1 to:30 do:[:idx| d at:idx printString put:idx]. val + 1]. |
|
435 d |
|
436 " |
|
437 |
|
438 " |
|
439 |d| |
|
440 |
|
441 d := Dictionary new. |
|
442 d at:'two' ifAbsent:0 update:[:val | val + 1]. |
|
443 d at:'two' ifAbsent:0 update:[:val | d removeKey:'two'. val + 1]. |
411 d |
444 d |
412 " |
445 " |
413 ! |
446 ! |
414 |
447 |
415 at:aKey ifAbsentPut:valueBlock |
448 at:aKey ifAbsentPut:valueBlock |
418 under aKey and return it. |
451 under aKey and return it. |
419 WARNING: do not add elements while iterating over the receiver. |
452 WARNING: do not add elements while iterating over the receiver. |
420 Iterate over a copy to do this." |
453 Iterate over a copy to do this." |
421 |
454 |
422 |index "{ Class: SmallInteger }" |
455 |index "{ Class: SmallInteger }" |
423 k newValue oldKeyArray| |
456 k newValue oldKeyArray probeKey| |
424 |
457 |
425 (k := aKey) isNil ifTrue:[ |
458 (k := aKey) isNil ifTrue:[ |
426 k := NilEntry |
459 k := NilEntry |
427 ]. |
460 ]. |
428 |
461 |
429 index := self findKeyOrNil:k. |
462 index := self findKeyOrNilOrDeletedEntry:k. |
430 (keyArray basicAt:index) notNil ifTrue:[ |
463 probeKey := keyArray basicAt:index. |
|
464 (probeKey notNil and:[probeKey ~~ DeletedEntry]) ifTrue:[ |
431 "/ key is already present |
465 "/ key is already present |
432 ^ valueArray at:index. |
466 ^ valueArray at:index. |
433 ]. |
467 ]. |
|
468 |
434 "/ a new key |
469 "/ a new key |
435 oldKeyArray := keyArray. |
470 oldKeyArray := keyArray. |
436 |
|
437 newValue := valueBlock value. |
471 newValue := valueBlock value. |
438 |
472 (keyArray ~~ oldKeyArray or:[(keyArray basicAt:index) ~~ probeKey]) ifTrue:[ |
439 (keyArray ~~ oldKeyArray or:[(keyArray basicAt:index) notNil]) ifTrue:[ |
|
440 "I have been changed while performing the valueBlock. |
473 "I have been changed while performing the valueBlock. |
441 have to find the key again." |
474 have to find the key again." |
442 index := self findKeyOrNil:k. |
475 index := self findKeyOrNil:k. |
443 (keyArray basicAt:index) notNil ifTrue:[ |
476 (keyArray basicAt:index) notNil ifTrue:[ |
444 "/ key is now present |
477 "/ key was not, but is now present. |
445 ^ valueArray at:index. |
478 "/ since we executed the valueBlock, overwrite the value in the Dictionary |
|
479 valueArray at:index put:newValue. |
|
480 ^ newValue |
446 ]. |
481 ]. |
447 ]. |
482 ]. |
448 "/ a new key... |
483 "/ a new key... |
449 keyArray basicAt:index put:k. |
484 keyArray basicAt:index put:k. |
450 valueArray basicAt:index put:newValue. |
485 valueArray basicAt:index put:newValue. |
461 Transcript showCR:(d at:'foo2' ifAbsentPut:'bar2'). |
496 Transcript showCR:(d at:'foo2' ifAbsentPut:'bar2'). |
462 Transcript showCR:(d at:'foo' ifAbsentPut:'barX'). |
497 Transcript showCR:(d at:'foo' ifAbsentPut:'barX'). |
463 Transcript showCR:(d at:'foo2' ifAbsentPut:'bar2X'). |
498 Transcript showCR:(d at:'foo2' ifAbsentPut:'bar2X'). |
464 " |
499 " |
465 |
500 |
|
501 " |
|
502 |d| |
|
503 |
|
504 d := Dictionary new. |
|
505 d at:'one' ifAbsentPut:[d at:'one' put:1. 33333]. |
|
506 d |
|
507 " |
|
508 |
|
509 " |
|
510 |d| |
|
511 |
|
512 d := Dictionary new. |
|
513 d at:'two' ifAbsentPut:[1 to:30 do:[:idx| d at:idx printString put:idx]. 2]. |
|
514 d |
|
515 " |
|
516 |
|
517 |
466 "Created: / 23.1.1998 / 18:28:26 / cg" |
518 "Created: / 23.1.1998 / 18:28:26 / cg" |
467 "Modified: / 26.2.1998 / 19:10:09 / stefan" |
519 "Modified: / 26.2.1998 / 19:10:09 / stefan" |
468 ! |
520 ! |
469 |
521 |
470 at:aKey ifPresent:aBlock |
522 at:aKey ifPresent:aBlock |
498 (k := aKey) isNil ifTrue:[ |
550 (k := aKey) isNil ifTrue:[ |
499 k := NilEntry |
551 k := NilEntry |
500 ]. |
552 ]. |
501 |
553 |
502 index := self findKeyOrNil:k. |
554 index := self findKeyOrNil:k. |
503 (keyArray basicAt:index) notNil ifTrue:[ |
|
504 "/ key already present |
|
505 valueArray basicAt:index put:anObject. |
|
506 ^ anObject |
|
507 ]. |
|
508 "/ a new key |
|
509 keyArray basicAt:index put:k. |
|
510 valueArray basicAt:index put:anObject. |
555 valueArray basicAt:index put:anObject. |
511 tally := tally + 1. |
556 (keyArray basicAt:index) isNil ifTrue:[ |
512 |
557 "/ a new key |
513 self possiblyGrow. |
558 keyArray basicAt:index put:k. |
|
559 tally := tally + 1. |
|
560 self possiblyGrow. |
|
561 ]. |
514 ^ anObject |
562 ^ anObject |
515 |
563 |
516 "Modified: 30.1.1997 / 14:59:10 / cg" |
564 "Modified: 30.1.1997 / 14:59:10 / cg" |
517 ! |
565 ! |
518 |
566 |
558 I.e. this is the same as self at:aKey put:(aBlock value:(self at:aKey)). |
606 I.e. this is the same as self at:aKey put:(aBlock value:(self at:aKey)). |
559 Return the new value stored. |
607 Return the new value stored. |
560 This is an optimized accessor, which only computes the hash value once." |
608 This is an optimized accessor, which only computes the hash value once." |
561 |
609 |
562 |k index "{ Class: SmallInteger }" |
610 |k index "{ Class: SmallInteger }" |
563 newValue| |
611 newValue oldKey oldKeyArray| |
564 |
612 |
565 (k := aKey) isNil ifTrue:[ |
613 (k := aKey) isNil ifTrue:[ |
566 k := NilEntry |
614 k := NilEntry |
567 ]. |
615 ]. |
568 |
616 |
569 index := self findKeyOrNil:k. |
617 index := self find:k ifAbsent:0. |
570 (keyArray basicAt:index) notNil ifTrue:[ |
618 index == 0 ifTrue:[ |
571 "/ key present |
619 "/ a new key |
572 valueArray basicAt:index put:(newValue := aBlock value:(valueArray basicAt:index)). |
620 ^ self errorKeyNotFound:k. |
573 ^ newValue |
621 ]. |
574 ]. |
622 |
575 "/ a new key |
623 "/ key present |
576 ^ self errorKeyNotFound:k. |
624 oldKey := keyArray basicAt:index. |
|
625 oldKeyArray := keyArray. |
|
626 newValue := aBlock value:(valueArray basicAt:index). |
|
627 (keyArray ~~ oldKeyArray or:[(keyArray basicAt:index) ~~ oldKey]) ifTrue:[ |
|
628 "I have been changed while performing aBlock. |
|
629 have to find the key again." |
|
630 index := self find:k ifAbsent:0. |
|
631 index == 0 ifTrue:[ |
|
632 "/ the key is gone while performing the block. |
|
633 ^ self errorKeyNotFound:k. |
|
634 ]. |
|
635 ]. |
|
636 |
|
637 valueArray basicAt:index put:newValue. |
|
638 ^ newValue |
577 |
639 |
578 " |
640 " |
579 |d| |
641 |d| |
580 |
642 |
581 d := Dictionary new. |
643 d := Dictionary new. |
582 d at:'one' update:[:val | val + 1]. |
644 d at:'one' update:[:val | val + 1]. |
|
645 " |
|
646 |
|
647 " |
|
648 |d| |
|
649 |
|
650 d := Dictionary new. |
|
651 d at:'one' put:0. |
|
652 d at:'one' update:[:val | d removeKey:'one'. val + 1]. |
583 " |
653 " |
584 |
654 |
585 " |
655 " |
586 |d| |
656 |d| |
587 d := Dictionary new. |
657 d := Dictionary new. |
590 d at:'three' put:0. |
660 d at:'three' put:0. |
591 |
661 |
592 d at:'one' update:[:val | val + 1]. |
662 d at:'one' update:[:val | val + 1]. |
593 d at:'two' update:[:val | val + 1]. |
663 d at:'two' update:[:val | val + 1]. |
594 d at:'three' update:[:val | val + 1]. |
664 d at:'three' update:[:val | val + 1]. |
595 d at:'one' update:[:val | val + 1]. |
|
596 d at:'two' update:[:val | val + 1]. |
665 d at:'two' update:[:val | val + 1]. |
|
666 d at:'three' update:[:val | val + 1]. |
|
667 d at:'three' update:[:val | val + 1]. |
597 d |
668 d |
598 " |
669 " |
599 ! |
670 ! |
600 |
671 |
601 keyAtEqualValue:aValue |
672 keyAtEqualValue:aValue |