Optimize memory footprint for SlicedMapImpl in case it's empty
It might be useful in case of many delegating traces that remain effectively empty themselves (up to 7M of empty maps in case of compilation of 'idea' module)
This commit is contained in:
@@ -23,6 +23,7 @@ import com.intellij.openapi.util.Key;
|
|||||||
import com.intellij.util.keyFMap.KeyFMap;
|
import com.intellij.util.keyFMap.KeyFMap;
|
||||||
import kotlin.jvm.functions.Function3;
|
import kotlin.jvm.functions.Function3;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -31,7 +32,8 @@ import java.util.Map;
|
|||||||
public class SlicedMapImpl implements MutableSlicedMap {
|
public class SlicedMapImpl implements MutableSlicedMap {
|
||||||
|
|
||||||
private final boolean alwaysAllowRewrite;
|
private final boolean alwaysAllowRewrite;
|
||||||
private final Map<Object, KeyFMap> map = new OpenAddressLinearProbingHashTable<>();
|
@Nullable
|
||||||
|
private Map<Object, KeyFMap> map = null;
|
||||||
private Multimap<WritableSlice<?, ?>, Object> collectiveSliceKeys = null;
|
private Multimap<WritableSlice<?, ?>, Object> collectiveSliceKeys = null;
|
||||||
|
|
||||||
public SlicedMapImpl(boolean alwaysAllowRewrite) {
|
public SlicedMapImpl(boolean alwaysAllowRewrite) {
|
||||||
@@ -44,6 +46,10 @@ public class SlicedMapImpl implements MutableSlicedMap {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (map == null) {
|
||||||
|
map = new OpenAddressLinearProbingHashTable<>();
|
||||||
|
}
|
||||||
|
|
||||||
KeyFMap holder = map.get(key);
|
KeyFMap holder = map.get(key);
|
||||||
if (holder == null) {
|
if (holder == null) {
|
||||||
holder = KeyFMap.EMPTY_MAP;
|
holder = KeyFMap.EMPTY_MAP;
|
||||||
@@ -76,13 +82,13 @@ public class SlicedMapImpl implements MutableSlicedMap {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clear() {
|
public void clear() {
|
||||||
map.clear();
|
map = null;
|
||||||
collectiveSliceKeys = null;
|
collectiveSliceKeys = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <K, V> V get(ReadOnlySlice<K, V> slice, K key) {
|
public <K, V> V get(ReadOnlySlice<K, V> slice, K key) {
|
||||||
KeyFMap holder = map.get(key);
|
KeyFMap holder = map != null ? map.get(key) : null;
|
||||||
|
|
||||||
V value = holder == null ? null : holder.get(slice.getKey());
|
V value = holder == null ? null : holder.get(slice.getKey());
|
||||||
|
|
||||||
@@ -100,6 +106,7 @@ public class SlicedMapImpl implements MutableSlicedMap {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void forEach(@NotNull Function3<WritableSlice, Object, Object, Void> f) {
|
public void forEach(@NotNull Function3<WritableSlice, Object, Object, Void> f) {
|
||||||
|
if (map == null) return;
|
||||||
map.forEach((key, holder) -> {
|
map.forEach((key, holder) -> {
|
||||||
if (holder == null) return;
|
if (holder == null) return;
|
||||||
|
|
||||||
@@ -114,6 +121,8 @@ public class SlicedMapImpl implements MutableSlicedMap {
|
|||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public <K, V> ImmutableMap<K, V> getSliceContents(@NotNull ReadOnlySlice<K, V> slice) {
|
public <K, V> ImmutableMap<K, V> getSliceContents(@NotNull ReadOnlySlice<K, V> slice) {
|
||||||
|
if (map == null) return ImmutableMap.of();
|
||||||
|
|
||||||
ImmutableMap.Builder<K, V> builder = ImmutableMap.builder();
|
ImmutableMap.Builder<K, V> builder = ImmutableMap.builder();
|
||||||
|
|
||||||
map.forEach((key, holder) -> {
|
map.forEach((key, holder) -> {
|
||||||
|
|||||||
Reference in New Issue
Block a user