Browse Source

Fix bug with deallocating `AssociativeArray`s keys

When key was deallocated, `AssociativeArray` attempted to free values
using that key's life version.
pull/8/head
Anton Tarasenko 3 years ago
parent
commit
41f95a7423
  1. 2
      sources/Data/Collections/AssociativeArray.uc
  2. 43
      sources/Data/Collections/Tests/TEST_AssociativeArray.uc

2
sources/Data/Collections/AssociativeArray.uc

@ -173,7 +173,7 @@ private final function CleanBucket(out Bucket bucketToClean)
if (nextEntry.key.GetLifeVersion() != nextEntry.keyLifeVersion) if (nextEntry.key.GetLifeVersion() != nextEntry.keyLifeVersion)
{ {
if (bucketEntries[i].value != none && bucketEntries[i].managed) { if (bucketEntries[i].value != none && bucketEntries[i].managed) {
bucketEntries[i].value.FreeSelf(nextEntry.keyLifeVersion); bucketEntries[i].value.FreeSelf(nextEntry.valueLifeVersion);
} }
bucketEntries.Remove(i, 1); bucketEntries.Remove(i, 1);
// We'll update the count, but won't trigger hash table size update // We'll update the count, but won't trigger hash table size update

43
sources/Data/Collections/Tests/TEST_AssociativeArray.uc

@ -281,6 +281,47 @@ protected static function Test_Managed()
} }
protected static function Test_DeallocationHandling() protected static function Test_DeallocationHandling()
{
Context("Testing how `AssociativeArray` deals with external deallocation of"
@ "keys and managed objects.");
SubTest_DeallocationHandlingKeys();
SubTest_DeallocationHandlingManagedObjects();
}
protected static function SubTest_DeallocationHandlingKeys()
{
local IntBox key1;
local BoolBox key2;
local Text key3;
local AssociativeArray array;
local array<AcediaObject> keys;
key1 = __().box.int(3881);
key2 = __().box.bool(true);
key3 = __().text.FromString("Text key, bay bee");
array = AssociativeArray(__().memory.Allocate(class'AssociativeArray'));
class'MockItem'.default.objectCount = 0;
array.SetItem(key1, NewMockItem());
array.SetItem(key2, __().box.float(32.31), true);
array.SetItem(key3, NewMockItem(), true);
Issue("Deallocating keys does not remove them from `AssociativeArray`.");
key1.FreeSelf();
key3.FreeSelf();
keys = array.GetKeys();
TEST_ExpectTrue(keys.length == 1);
TEST_ExpectTrue(keys[0] == key2);
Issue("`AssociativeArray` does not deallocate managed objects, even though"
@ "their keys were deallocated");
TEST_ExpectTrue(class'MockItem'.default.objectCount < 2);
TEST_ExpectNone(array.GetItem(__().box.int(3881)));
Issue("`AssociativeArray` deallocates unmanaged objects, when"
@ "their keys were deallocated");
TEST_ExpectTrue(class'MockItem'.default.objectCount > 0);
}
protected static function SubTest_DeallocationHandlingManagedObjects()
{ {
local MockItem exampleItem; local MockItem exampleItem;
local AssociativeArray array; local AssociativeArray array;
@ -292,8 +333,6 @@ protected static function Test_DeallocationHandling()
array.SetItem(__().box.int(23), NewMockItem()); array.SetItem(__().box.int(23), NewMockItem());
array.SetItem(__().box.int(242), NewMockItem(), true); array.SetItem(__().box.int(242), NewMockItem(), true);
array.CreateItem(__().box.int(24532), class'MockItem'); array.CreateItem(__().box.int(24532), class'MockItem');
Context("Testing how `AssociativeArray` deals with external deallocation of"
@ "managed objects.");
Issue("`AssociativeArray` does not return `none` even though stored object" Issue("`AssociativeArray` does not return `none` even though stored object"
@ "was already deallocated."); @ "was already deallocated.");
array.GetItem(__().box.int(23)).FreeSelf(); array.GetItem(__().box.int(23)).FreeSelf();

Loading…
Cancel
Save