Dictionary.st
branchjv
changeset 20244 20922299fd44
parent 20229 b5cdb27022c8
parent 20239 cc11bc01e248
child 20398 8cb53f870d39
equal deleted inserted replaced
20229:b5cdb27022c8 20244:20922299fd44
   292         ( aDictionary at: key ifAbsent: [ ^false ] ) = value
   292         ( aDictionary at: key ifAbsent: [ ^false ] ) = value
   293         ifFalse: [ ^false ]
   293         ifFalse: [ ^false ]
   294     ].
   294     ].
   295     ^ true
   295     ^ true
   296 ! !
   296 ! !
       
   297 
   297 
   298 
   298 
   299 
   299 !Dictionary methodsFor:'accessing'!
   300 !Dictionary methodsFor:'accessing'!
   300 
   301 
   301 associationAt:aKey
   302 associationAt:aKey
   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