This is an automated email from the ASF dual-hosted git repository. pkarwasz pushed a commit to branch 2.x in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit d092e9f8748fa3f82c04b671af5ea0b40722054a Author: John Engebretson <[email protected]> AuthorDate: Thu Feb 29 18:37:25 2024 +0000 Performance bug fix w/ test --- .../log4j/spi/UnmodifiableArrayBackedMapTest.java | 20 ++++++++++++++++++++ .../log4j/spi/UnmodifiableArrayBackedMap.java | 9 ++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/log4j-api-test/src/test/java/org/apache/logging/log4j/spi/UnmodifiableArrayBackedMapTest.java b/log4j-api-test/src/test/java/org/apache/logging/log4j/spi/UnmodifiableArrayBackedMapTest.java index af8f2f85be..16d2c696b7 100644 --- a/log4j-api-test/src/test/java/org/apache/logging/log4j/spi/UnmodifiableArrayBackedMapTest.java +++ b/log4j-api-test/src/test/java/org/apache/logging/log4j/spi/UnmodifiableArrayBackedMapTest.java @@ -216,6 +216,7 @@ public class UnmodifiableArrayBackedMapTest { @Test public void testCopyAndRemove() { + // general removing from well-populated set HashMap<String, String> params = getTestParameters(); UnmodifiableArrayBackedMap testMap = UnmodifiableArrayBackedMap.EMPTY_MAP.copyAndPutAll(params); testMap = testMap.copyAndRemove("2"); @@ -224,6 +225,25 @@ public class UnmodifiableArrayBackedMapTest { assertFalse(testMap.containsKey("2")); assertTrue(testMap.containsKey("1")); assertFalse(testMap.containsValue("value2")); + + // test removing from empty set + testMap = UnmodifiableArrayBackedMap.EMPTY_MAP.copyAndPut("test", "test"); + testMap = testMap.copyAndRemove("test"); + assertTrue(testMap.isEmpty()); + + // test removing first of two elements + testMap = UnmodifiableArrayBackedMap.EMPTY_MAP.copyAndPut("test1", "test1"); + testMap = testMap.copyAndPut("test2", "test2"); + testMap = testMap.copyAndRemove("test1"); + assertFalse(testMap.containsKey("test1")); + assertTrue(testMap.containsKey("test2")); + + // test removing second of two elements + testMap = UnmodifiableArrayBackedMap.EMPTY_MAP.copyAndPut("test1", "test1"); + testMap = testMap.copyAndPut("test2", "test2"); + testMap = testMap.copyAndRemove("test2"); + assertTrue(testMap.containsKey("test1")); + assertFalse(testMap.containsKey("test2")); } /** diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/spi/UnmodifiableArrayBackedMap.java b/log4j-api/src/main/java/org/apache/logging/log4j/spi/UnmodifiableArrayBackedMap.java index b5d583cc68..849d23bf06 100644 --- a/log4j-api/src/main/java/org/apache/logging/log4j/spi/UnmodifiableArrayBackedMap.java +++ b/log4j-api/src/main/java/org/apache/logging/log4j/spi/UnmodifiableArrayBackedMap.java @@ -305,12 +305,15 @@ class UnmodifiableArrayBackedMap extends AbstractMap<String, String> implements if (indexToRemove == -1) { // key not found, no change necessary return this; + } else if (numEntries == 1) { + // we have 1 item and we're about to remove it + return EMPTY_MAP; } if (indexToRemove > 0) { // copy entries before the removed one System.arraycopy(backingArray, 1, newMap.backingArray, 1, indexToRemove * 2); } - if (indexToRemove < (numEntries + 1)) { + if (indexToRemove + 1 < numEntries) { // copy entries after the removed one int nextIndexToCopy = indexToRemove + 1; int numRemainingEntries = numEntries - nextIndexToCopy; @@ -397,6 +400,10 @@ class UnmodifiableArrayBackedMap extends AbstractMap<String, String> implements numEntriesKept += numEntriesToCopy; } + if (numEntriesKept == 0) { + return EMPTY_MAP; + } + newMap.numEntries = numEntriesKept; newMap.updateNumEntriesInArray();
