From 364ed19c4bae03092f8ec27db8cbd776ec84f62e Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Wed, 15 May 2013 12:47:33 +0400 Subject: [PATCH] Simple implementations for lazy values and memoized functions --- .../MemoizedFunctionToNotNullImpl.java | 43 +++++++++++++++ .../MemoizedFunctionToNullableImpl.java | 53 +++++++++++++++++++ .../lazy/storage/NotNullLazyValueImpl.java | 34 ++++++++++++ .../lazy/storage/NullableLazyValueImpl.java | 44 +++++++++++++++ 4 files changed, 174 insertions(+) create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/storage/MemoizedFunctionToNotNullImpl.java create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/storage/MemoizedFunctionToNullableImpl.java create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/storage/NotNullLazyValueImpl.java create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/storage/NullableLazyValueImpl.java diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/storage/MemoizedFunctionToNotNullImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/storage/MemoizedFunctionToNotNullImpl.java new file mode 100644 index 00000000000..26299ceeb83 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/storage/MemoizedFunctionToNotNullImpl.java @@ -0,0 +1,43 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.lang.resolve.lazy.storage; + +import org.jetbrains.annotations.NotNull; + +import java.util.Map; + +public abstract class MemoizedFunctionToNotNullImpl extends MemoizedFunctionToNullableImpl implements MemoizedFunctionToNotNull { + + public MemoizedFunctionToNotNullImpl() { + } + + public MemoizedFunctionToNotNullImpl(@NotNull Map map) { + super(map); + } + + @NotNull + @Override + public V fun(K input) { + V result = super.fun(input); + assert result != null : "compute() returned null"; + return result; + } + + @NotNull + @Override + protected abstract V doCompute(K input); +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/storage/MemoizedFunctionToNullableImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/storage/MemoizedFunctionToNullableImpl.java new file mode 100644 index 00000000000..f678514cd4d --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/storage/MemoizedFunctionToNullableImpl.java @@ -0,0 +1,53 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.lang.resolve.lazy.storage; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.utils.WrappedValues; + +import java.util.HashMap; +import java.util.Map; + +public abstract class MemoizedFunctionToNullableImpl implements MemoizedFunctionToNullable { + private final Map cache; + + public MemoizedFunctionToNullableImpl() { + this(new HashMap()); + } + + public MemoizedFunctionToNullableImpl(@NotNull Map map) { + this.cache = map; + } + + @Nullable + @Override + public V fun(K input) { + Object value = cache.get(input); + if (value != null) return WrappedValues.unescapeNull(value); + + V typedValue = doCompute(input); + + Object oldValue = cache.put(input, WrappedValues.escapeNull(typedValue)); + assert oldValue == null : "Race condition detected"; + + return typedValue; + } + + @Nullable + protected abstract V doCompute(K input); +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/storage/NotNullLazyValueImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/storage/NotNullLazyValueImpl.java new file mode 100644 index 00000000000..d8ecc6eba16 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/storage/NotNullLazyValueImpl.java @@ -0,0 +1,34 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.lang.resolve.lazy.storage; + +import org.jetbrains.annotations.NotNull; + +public abstract class NotNullLazyValueImpl extends NullableLazyValueImpl implements NotNullLazyValue { + + @NotNull + @Override + public T compute() { + T result = super.compute(); + assert result != null : "compute() returned null"; + return result; + } + + @NotNull + @Override + protected abstract T doCompute(); +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/storage/NullableLazyValueImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/storage/NullableLazyValueImpl.java new file mode 100644 index 00000000000..dcf28af916e --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/storage/NullableLazyValueImpl.java @@ -0,0 +1,44 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.lang.resolve.lazy.storage; + +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.utils.WrappedValues; + +public abstract class NullableLazyValueImpl implements NullableLazyValue { + @Nullable + private Object value = null; + + @Override + public T compute() { + Object _value = value; + if (_value != null) return WrappedValues.unescapeNull(_value); + + T typedValue = doCompute(); + value = WrappedValues.escapeNull(typedValue); + + postCompute(typedValue); + + return typedValue; + } + + protected abstract T doCompute(); + + protected void postCompute(T value) { + // Doing something in post-compute helps prevent infinite recursion + } +}