Bug 43515

Critical

GemStone/S 64 Bit

3.1.0.5, 3.1.0.4, 3.1.0.3, 3.1.0.2, 3.1.0.1, 3.1, 3.0.1, 3.0, 2.4.4.8, 2.4.4.7, 2.4.4.6, 2.4.4.5, 2.4.4.4, 2.3.1.6, 2.2.5.4

All Platforms

3.2, 3.1.0.6, 2.4.6

Corruption problem on large IdentityDictionaries

When working with IdentityDictionaries with over 20K entries, there is
a risk that the value assigned to a key will be the association containing
the key and value rather than the expected value.  For example:

After performing:

anIdentityDict at: #key put: #value.
^ anIdentityDict at: #key

Rather than returning #value as expected, the code could return the Association
#key -> #value.

Workaround

Login as SystemUser and file-in / commit the code below.

! Patch for bug 43515 on GS/64 2.X - 3.1.0.5
!
category: 'Private'
method: KeyValueDictionary
_rebuildAt: aKey put: aValue

  self _rebuild ; at: aKey put: aValue
%

category: 'Private'
method: IdentityCollisionBucket
at: aKey put: aValue keyValDict_coll: aKeyValDict

"Private.  Adds the key-value pair (aKey, aValue) to the collision bucket.
 Returns 1 if this at:put: added a new key, 0 if this at:put:
 replaced the value for an existing  key .  "

| marker |

aKey == nil ifTrue:[ ^ self _error: #rtErrNilKey ] .

marker := self binarySearchForInsertKey: aKey.
marker < 0 ifTrue:[ "replace existing key"
  self at: marker negated putValue: aValue.
  aKeyValDict _markDirty .
  ^ 0
  ].
(numElements >= 974) ifTrue:[
  aKeyValDict _rebuildAt: aKey put: aValue .
  ^ 0
  ].
self insertAt: marker key: aKey value: aValue.
^ 1
%

category: 'Private'
method: IdentityDictionary
_rebuildAt: aKey put: aValue

  ^ self _rebuild ; _at: aKey put: aValue
%

Last updated: 5/8/14