*/
package org.opendaylight.yangtools.yang.data.impl.schema.nodes;
-import com.google.common.base.Preconditions;
+import static java.util.Objects.requireNonNull;
+
import com.google.common.collect.ImmutableMap;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
* Internal equivalent of {@link Collections}' unmodifiable Map. It does not retain
* keySet/entrySet references, thus lowering the memory overhead.
*/
-final class UnmodifiableChildrenMap implements Map<PathArgument, DataContainerChild<? extends PathArgument, ?>>, Serializable {
+final class UnmodifiableChildrenMap
+ implements CloneableMap<PathArgument, DataContainerChild<? extends PathArgument, ?>>, Serializable {
private static final long serialVersionUID = 1L;
+
+ /*
+ * Do not wrap maps which are smaller than this and instead copy them into an ImmutableMap.
+ */
+ private static final int WRAP_THRESHOLD = 9;
+
+ @SuppressFBWarnings(value = "SE_BAD_FIELD", justification = "Delegate is expected to be Serializable")
private final Map<PathArgument, DataContainerChild<? extends PathArgument, ?>> delegate;
- private transient Collection<DataContainerChild<? extends PathArgument, ?>> values;
+
+ private transient Collection<DataContainerChild<? extends PathArgument, ?>> values = null;
private UnmodifiableChildrenMap(final Map<PathArgument, DataContainerChild<? extends PathArgument, ?>> delegate) {
- this.delegate = Preconditions.checkNotNull(delegate);
+ this.delegate = requireNonNull(delegate);
}
/**
* @param map Backing map
* @return Unmodifiable view
*/
- static Map<PathArgument, DataContainerChild<? extends PathArgument, ?>> create(final Map<PathArgument, DataContainerChild<? extends PathArgument, ?>> map) {
+ static Map<PathArgument, DataContainerChild<? extends PathArgument, ?>> create(
+ final Map<PathArgument, DataContainerChild<? extends PathArgument, ?>> map) {
if (map instanceof UnmodifiableChildrenMap) {
return map;
}
return map;
}
if (map.isEmpty()) {
- return Collections.emptyMap();
+ return ImmutableMap.of();
+ }
+ if (map.size() < WRAP_THRESHOLD) {
+ return ImmutableMap.copyOf(map);
}
return new UnmodifiableChildrenMap(map);
}
@Override
+ @SuppressWarnings("checkstyle:parameterName")
public void putAll(final Map<? extends PathArgument, ? extends DataContainerChild<? extends PathArgument, ?>> m) {
throw new UnsupportedOperationException();
}
}
@Override
- public boolean equals(final Object o) {
- return this == o || delegate.equals(o);
+ public boolean equals(final Object obj) {
+ return this == obj || delegate.equals(obj);
}
@Override
public String toString() {
return delegate.toString();
}
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public Map<PathArgument, DataContainerChild<? extends PathArgument, ?>> createMutableClone() {
+ if (delegate instanceof HashMap) {
+ return (Map<PathArgument, DataContainerChild<? extends PathArgument, ?>>)
+ ((HashMap<?, ?>) delegate).clone();
+ }
+
+ return new HashMap<>(delegate);
+ }
}