From 912b086d2fa98dcc9224cc7635701e6e52dc8ffb Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Tue, 16 Jun 2015 00:28:54 +0200 Subject: [PATCH] Introduce MapAdaptor.initialSnapshot() In some circumstances we have an idea about how many entries will there be in a map. This could cost us perform one additional copy, so expose a method to create the appropriate map, behaving just as the one returned by takeSnapshot(Collections.emptyMap()). Also use ImmutableMaps for empty map, as it being immutable is recognized by Guava, leading to quick reuse. Change-Id: I40925e5d643c074277e9d11365a3b10fb9f22c1d Signed-off-by: Robert Varga (cherry picked from commit 92fc5cc4436a65c3a63e1fc7afbff2ac42a70880) --- .../yangtools/util/MapAdaptor.java | 20 ++++++++++++++++++- .../yangtools/util/ReadWriteTrieMap.java | 11 ++++++---- .../yangtools/util/MapAdaptorTest.java | 7 +++---- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/common/util/src/main/java/org/opendaylight/yangtools/util/MapAdaptor.java b/common/util/src/main/java/org/opendaylight/yangtools/util/MapAdaptor.java index bea7630330..48241cd5a6 100644 --- a/common/util/src/main/java/org/opendaylight/yangtools/util/MapAdaptor.java +++ b/common/util/src/main/java/org/opendaylight/yangtools/util/MapAdaptor.java @@ -8,6 +8,8 @@ package org.opendaylight.yangtools.util; import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; import com.romix.scala.collection.concurrent.TrieMap; import java.util.Collections; import java.util.HashMap; @@ -85,6 +87,22 @@ public final class MapAdaptor { return new MapAdaptor(useSingleton, copyMaxItems, persistMinItems); } + /** + * Creates an initial snapshot. The backing map is selected according to + * the expected size. + * + * @param expectedSize Expected map size + * @return An empty mutable map. + */ + public Map initialSnapshot(final int expectedSize) { + Preconditions.checkArgument(expectedSize >= 0); + if (expectedSize > persistMinItems) { + return new ReadWriteTrieMap<>(); + } + + return Maps.newHashMapWithExpectedSize(expectedSize); + } + /** * Input is treated is supposed to be left unmodified, result must be mutable. * @@ -124,7 +142,7 @@ public final class MapAdaptor { */ if (size == 0) { LOG.trace("Reducing input {} to an empty map", input); - return Collections.emptyMap(); + return ImmutableMap.of(); } /* diff --git a/common/util/src/main/java/org/opendaylight/yangtools/util/ReadWriteTrieMap.java b/common/util/src/main/java/org/opendaylight/yangtools/util/ReadWriteTrieMap.java index 039e7340a5..99cb628f89 100644 --- a/common/util/src/main/java/org/opendaylight/yangtools/util/ReadWriteTrieMap.java +++ b/common/util/src/main/java/org/opendaylight/yangtools/util/ReadWriteTrieMap.java @@ -7,17 +7,15 @@ */ package org.opendaylight.yangtools.util; +import com.google.common.base.Preconditions; +import com.romix.scala.collection.concurrent.TrieMap; import java.util.Collection; import java.util.Collections; import java.util.Map; import java.util.Set; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.base.Preconditions; -import com.romix.scala.collection.concurrent.TrieMap; - /** * A TrieMap facade tracking modifications. Since we change structures based on * their size, and determining the size of a TrieMap is expensive, we make sure @@ -34,6 +32,11 @@ final class ReadWriteTrieMap implements Map { private final TrieMap delegate; private int size; + ReadWriteTrieMap() { + this.delegate = new TrieMap(); + this.size = 0; + } + ReadWriteTrieMap(final TrieMap delegate, final int size) { this.delegate = Preconditions.checkNotNull(delegate); this.size = size; diff --git a/common/util/src/test/java/org/opendaylight/yangtools/util/MapAdaptorTest.java b/common/util/src/test/java/org/opendaylight/yangtools/util/MapAdaptorTest.java index e4ae622121..ec3b982dc8 100644 --- a/common/util/src/test/java/org/opendaylight/yangtools/util/MapAdaptorTest.java +++ b/common/util/src/test/java/org/opendaylight/yangtools/util/MapAdaptorTest.java @@ -11,12 +11,11 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; - +import com.google.common.collect.ImmutableMap; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.TreeMap; - import org.junit.Before; import org.junit.Test; @@ -38,10 +37,10 @@ public class MapAdaptorTest { assertTrue(snap instanceof HashMap); final Map opt1 = adaptor.optimize(input); - assertSame(Collections.EMPTY_MAP, opt1); + assertSame(ImmutableMap.of(), opt1); final Map opt2 = adaptor.optimize(snap); - assertSame(Collections.EMPTY_MAP, opt2); + assertSame(ImmutableMap.of(), opt2); } @Test -- 2.36.6