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 <rovarga@cisco.com>
(cherry picked from commit
92fc5cc4436a65c3a63e1fc7afbff2ac42a70880)
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;
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 <K, V> Map<K, V> 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.
*
*/
if (size == 0) {
LOG.trace("Reducing input {} to an empty map", input);
- return Collections.emptyMap();
+ return ImmutableMap.of();
}
/*
*/
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
private final TrieMap<K, V> delegate;
private int size;
+ ReadWriteTrieMap() {
+ this.delegate = new TrieMap<K, V>();
+ this.size = 0;
+ }
+
ReadWriteTrieMap(final TrieMap<K, V> delegate, final int size) {
this.delegate = Preconditions.checkNotNull(delegate);
this.size = size;
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;
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