Dictionary.st
changeset 16902 869a0975a957
parent 16808 793e0523328e
child 17264 548ea4dc5aa4
--- a/Dictionary.st	Sat Oct 18 13:17:48 2014 +0200
+++ b/Dictionary.st	Mon Oct 20 15:45:24 2014 +0200
@@ -230,7 +230,6 @@
     ^ self = aDictionary
 ! !
 
-
 !Dictionary methodsFor:'accessing'!
 
 associationAt:aKey
@@ -305,6 +304,48 @@
     ^ exceptionBlock value.
 !
 
+at:aKey ifAbsent:default update:aBlock 
+    "update the element stored under aKey with the result from 
+     evaluating aBlock with the previous stored value as argument, or with default,
+     if there was no such key initially.
+     I.e. this is the same as self at:aKey put:(aBlock value:(self at:aKey ifAbsent:default)).
+     Return the new value stored.
+     This is an optimized accessor, which only computes the hash value once."
+
+    |k index "{ Class: SmallInteger }"
+     newValue|
+
+    (k := aKey) isNil ifTrue:[
+        k := NilEntry
+    ].
+
+    index := self findKeyOrNil:k.
+    (keyArray basicAt:index) notNil ifTrue:[
+        "/ key present
+        valueArray basicAt:index put:(newValue := aBlock value:(valueArray basicAt:index)).
+        ^ newValue
+    ].
+    "/ a new key
+    keyArray basicAt:index put:k.
+    valueArray basicAt:index put:(newValue := aBlock value:default).
+    tally := tally + 1.
+
+    self fullCheck.
+    ^ newValue
+
+    "
+     |d|
+
+     d := Dictionary new.
+     d at:'one'  ifAbsent:0 update:[:val | val + 1].
+     d at:'two'  ifAbsent:0 update:[:val | val + 1].
+     d at:'three' ifAbsent:0  update:[:val | val + 1].
+     d at:'one' ifAbsent:0  update:[:val | val + 1].
+     d at:'two' ifAbsent:0  update:[:val | val + 1].
+     d
+    "
+!
+
 at:aKey ifAbsentPut:valueBlock
     "return the element indexed by aKey if present,
      if not present, store the result of evaluating valueBlock
@@ -406,6 +447,53 @@
     "
 !
 
+at:aKey update:aBlock 
+    "update the element stored under aKey with the result from 
+     evaluating aBlock with the previous stored value as argument.
+     Report an error if there was no such key initially.
+     I.e. this is the same as self at:aKey put:(aBlock value:(self at:aKey)).
+     Return the new value stored.
+     This is an optimized accessor, which only computes the hash value once."
+
+    |k index "{ Class: SmallInteger }"
+     newValue|
+
+    (k := aKey) isNil ifTrue:[
+        k := NilEntry
+    ].
+
+    index := self findKeyOrNil:k.
+    (keyArray basicAt:index) notNil ifTrue:[
+        "/ key present
+        valueArray basicAt:index put:(newValue := aBlock value:(valueArray basicAt:index)).
+        ^ newValue
+    ].
+    "/ a new key
+    ^ self errorKeyNotFound:k.
+
+    "
+     |d|
+
+     d := Dictionary new.
+     d at:'one'  update:[:val | val + 1].
+    "
+
+    "
+     |d|
+     d := Dictionary new.
+     d at:'one' put:0.
+     d at:'two' put:0.
+     d at:'three' put:0.
+
+     d at:'one'    update:[:val | val + 1].
+     d at:'two'    update:[:val | val + 1].
+     d at:'three'  update:[:val | val + 1].
+     d at:'one'    update:[:val | val + 1].
+     d at:'two'    update:[:val | val + 1].
+     d
+    "
+!
+
 keyAtEqualValue:aValue
     "return the key whose value is equal (i.e. using #= for compare)
      to the argument, nil if none found.
@@ -2157,10 +2245,10 @@
 !Dictionary class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/Dictionary.st,v 1.121 2014-08-01 12:52:05 stefan Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/Dictionary.st,v 1.122 2014-10-20 13:45:24 cg Exp $'
 !
 
 version_CVS
-    ^ '$Header: /cvs/stx/stx/libbasic/Dictionary.st,v 1.121 2014-08-01 12:52:05 stefan Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/Dictionary.st,v 1.122 2014-10-20 13:45:24 cg Exp $'
 ! !