Skip to content

Commit

Permalink
Merge pull request #513 from ruslansennov/infLoop2
Browse files Browse the repository at this point in the history
Infinite loop in Function* fixed
  • Loading branch information
danieldietrich committed Aug 25, 2015
2 parents 9802bcb + 16e4bbc commit 7b56ccd
Show file tree
Hide file tree
Showing 35 changed files with 326 additions and 52 deletions.
32 changes: 28 additions & 4 deletions generator/Generator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -505,12 +505,26 @@ def generateMainClasses(): Unit = {
return ($className$fullGenerics & Memoized) Lazy.of($mappingFunction)::get;
""" else if (i == 1) xs"""
final Lazy<R> forNull = Lazy.of($forNull);
final ${im.getType("java.util.Map")}<$generics, R> cache = new ${im.getType("java.util.concurrent.ConcurrentHashMap")}<>();
return ($className$fullGenerics & Memoized) t1 -> (t1 == null) ? forNull.get() : cache.computeIfAbsent(t1, $mappingFunction);
final Object lock = new Object();
final ${im.getType("java.util.Map")}<$generics, R> cache = new ${im.getType("java.util.HashMap")}<>();
return ($className$fullGenerics & Memoized) t1 -> {
if (t1 == null) {
return forNull.get();
} else {
synchronized (lock) {
return cache.computeIfAbsent(t1, $mappingFunction);
}
}
};
""" else xs"""
final ${im.getType("java.util.Map")}<Tuple$i<$generics>, R> cache = new ${im.getType("java.util.concurrent.ConcurrentHashMap")}<>();
final Object lock = new Object();
final ${im.getType("java.util.Map")}<Tuple$i<$generics>, R> cache = new ${im.getType("java.util.HashMap")}<>();
final ${checked.gen("Checked")}Function1<Tuple$i<$generics>, R> tupled = tupled();
return ($className$fullGenerics & Memoized) ($params) -> cache.computeIfAbsent(Tuple.of($params), $mappingFunction);
return ($className$fullGenerics & Memoized) ($params) -> {
synchronized (lock) {
return cache.computeIfAbsent(Tuple.of($params), $mappingFunction);
}
};
"""
}
}
Expand Down Expand Up @@ -759,6 +773,7 @@ def generateTestClasses(): Unit = {

val test = im.getType("org.junit.Test")
val assertThat = im.getStatic("org.assertj.core.api.Assertions.assertThat")
val recFuncF1 = if (i == 0) "11;" else s"i1 <= 0 ? i1 : $className.recurrent2.apply(${(1 to i).gen(j => s"i$j" + (j == 1).gen(s" - 1"))(", ")}) + 1;"

def curriedType(max: Int, function: String): String = {
if (max == 0) {
Expand Down Expand Up @@ -885,6 +900,15 @@ def generateTestClasses(): Unit = {
$assertThat(memo.isMemoized()).isTrue();
}

private static $name$i<${(1 to i + 1).gen(j => "Integer")(", ")}> recurrent1 = (${(1 to i).gen(j => s"i$j")(", ")}) -> $recFuncF1
private static $name$i<${(1 to i + 1).gen(j => "Integer")(", ")}> recurrent2 = $className.recurrent1.memoized();

@$test
public void shouldCalculatedRecursively()${checked.gen(" throws Throwable")} {
assertThat(recurrent1.apply(${(1 to i).gen(j => "11")(", ")})).isEqualTo(11);
${(i > 0).gen(s"assertThat(recurrent1.apply(${(1 to i).gen(j => "22")(", ")})).isEqualTo(22);")}
}

@$test
public void shouldComposeWithAndThen() {
final $name$i<$generics> f = ($functionArgs) -> null;
Expand Down
15 changes: 12 additions & 3 deletions src-gen/main/java/javaslang/CheckedFunction1.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
G E N E R A T O R C R A F T E D
\*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import javaslang.control.Try;

/**
Expand Down Expand Up @@ -139,8 +139,17 @@ default CheckedFunction1<T1, R> memoized() {
return this;
} else {
final Lazy<R> forNull = Lazy.of(Try.of(() -> apply(null))::get);
final Map<T1, R> cache = new ConcurrentHashMap<>();
return (CheckedFunction1<T1, R> & Memoized) t1 -> (t1 == null) ? forNull.get() : cache.computeIfAbsent(t1, t -> Try.of(() -> this.apply(t)).get());
final Object lock = new Object();
final Map<T1, R> cache = new HashMap<>();
return (CheckedFunction1<T1, R> & Memoized) t1 -> {
if (t1 == null) {
return forNull.get();
} else {
synchronized (lock) {
return cache.computeIfAbsent(t1, t -> Try.of(() -> this.apply(t)).get());
}
}
};
}
}

Expand Down
11 changes: 8 additions & 3 deletions src-gen/main/java/javaslang/CheckedFunction2.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
G E N E R A T O R C R A F T E D
\*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import javaslang.control.Try;

/**
Expand Down Expand Up @@ -147,9 +147,14 @@ default CheckedFunction2<T1, T2, R> memoized() {
if (this instanceof Memoized) {
return this;
} else {
final Map<Tuple2<T1, T2>, R> cache = new ConcurrentHashMap<>();
final Object lock = new Object();
final Map<Tuple2<T1, T2>, R> cache = new HashMap<>();
final CheckedFunction1<Tuple2<T1, T2>, R> tupled = tupled();
return (CheckedFunction2<T1, T2, R> & Memoized) (t1, t2) -> cache.computeIfAbsent(Tuple.of(t1, t2), t -> Try.of(() -> tupled.apply(t)).get());
return (CheckedFunction2<T1, T2, R> & Memoized) (t1, t2) -> {
synchronized (lock) {
return cache.computeIfAbsent(Tuple.of(t1, t2), t -> Try.of(() -> tupled.apply(t)).get());
}
};
}
}

Expand Down
11 changes: 8 additions & 3 deletions src-gen/main/java/javaslang/CheckedFunction3.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
G E N E R A T O R C R A F T E D
\*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import javaslang.control.Try;

/**
Expand Down Expand Up @@ -167,9 +167,14 @@ default CheckedFunction3<T1, T2, T3, R> memoized() {
if (this instanceof Memoized) {
return this;
} else {
final Map<Tuple3<T1, T2, T3>, R> cache = new ConcurrentHashMap<>();
final Object lock = new Object();
final Map<Tuple3<T1, T2, T3>, R> cache = new HashMap<>();
final CheckedFunction1<Tuple3<T1, T2, T3>, R> tupled = tupled();
return (CheckedFunction3<T1, T2, T3, R> & Memoized) (t1, t2, t3) -> cache.computeIfAbsent(Tuple.of(t1, t2, t3), t -> Try.of(() -> tupled.apply(t)).get());
return (CheckedFunction3<T1, T2, T3, R> & Memoized) (t1, t2, t3) -> {
synchronized (lock) {
return cache.computeIfAbsent(Tuple.of(t1, t2, t3), t -> Try.of(() -> tupled.apply(t)).get());
}
};
}
}

Expand Down
11 changes: 8 additions & 3 deletions src-gen/main/java/javaslang/CheckedFunction4.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
G E N E R A T O R C R A F T E D
\*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import javaslang.control.Try;

/**
Expand Down Expand Up @@ -188,9 +188,14 @@ default CheckedFunction4<T1, T2, T3, T4, R> memoized() {
if (this instanceof Memoized) {
return this;
} else {
final Map<Tuple4<T1, T2, T3, T4>, R> cache = new ConcurrentHashMap<>();
final Object lock = new Object();
final Map<Tuple4<T1, T2, T3, T4>, R> cache = new HashMap<>();
final CheckedFunction1<Tuple4<T1, T2, T3, T4>, R> tupled = tupled();
return (CheckedFunction4<T1, T2, T3, T4, R> & Memoized) (t1, t2, t3, t4) -> cache.computeIfAbsent(Tuple.of(t1, t2, t3, t4), t -> Try.of(() -> tupled.apply(t)).get());
return (CheckedFunction4<T1, T2, T3, T4, R> & Memoized) (t1, t2, t3, t4) -> {
synchronized (lock) {
return cache.computeIfAbsent(Tuple.of(t1, t2, t3, t4), t -> Try.of(() -> tupled.apply(t)).get());
}
};
}
}

Expand Down
11 changes: 8 additions & 3 deletions src-gen/main/java/javaslang/CheckedFunction5.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
G E N E R A T O R C R A F T E D
\*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import javaslang.control.Try;

/**
Expand Down Expand Up @@ -210,9 +210,14 @@ default CheckedFunction5<T1, T2, T3, T4, T5, R> memoized() {
if (this instanceof Memoized) {
return this;
} else {
final Map<Tuple5<T1, T2, T3, T4, T5>, R> cache = new ConcurrentHashMap<>();
final Object lock = new Object();
final Map<Tuple5<T1, T2, T3, T4, T5>, R> cache = new HashMap<>();
final CheckedFunction1<Tuple5<T1, T2, T3, T4, T5>, R> tupled = tupled();
return (CheckedFunction5<T1, T2, T3, T4, T5, R> & Memoized) (t1, t2, t3, t4, t5) -> cache.computeIfAbsent(Tuple.of(t1, t2, t3, t4, t5), t -> Try.of(() -> tupled.apply(t)).get());
return (CheckedFunction5<T1, T2, T3, T4, T5, R> & Memoized) (t1, t2, t3, t4, t5) -> {
synchronized (lock) {
return cache.computeIfAbsent(Tuple.of(t1, t2, t3, t4, t5), t -> Try.of(() -> tupled.apply(t)).get());
}
};
}
}

Expand Down
11 changes: 8 additions & 3 deletions src-gen/main/java/javaslang/CheckedFunction6.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
G E N E R A T O R C R A F T E D
\*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import javaslang.control.Try;

/**
Expand Down Expand Up @@ -233,9 +233,14 @@ default CheckedFunction6<T1, T2, T3, T4, T5, T6, R> memoized() {
if (this instanceof Memoized) {
return this;
} else {
final Map<Tuple6<T1, T2, T3, T4, T5, T6>, R> cache = new ConcurrentHashMap<>();
final Object lock = new Object();
final Map<Tuple6<T1, T2, T3, T4, T5, T6>, R> cache = new HashMap<>();
final CheckedFunction1<Tuple6<T1, T2, T3, T4, T5, T6>, R> tupled = tupled();
return (CheckedFunction6<T1, T2, T3, T4, T5, T6, R> & Memoized) (t1, t2, t3, t4, t5, t6) -> cache.computeIfAbsent(Tuple.of(t1, t2, t3, t4, t5, t6), t -> Try.of(() -> tupled.apply(t)).get());
return (CheckedFunction6<T1, T2, T3, T4, T5, T6, R> & Memoized) (t1, t2, t3, t4, t5, t6) -> {
synchronized (lock) {
return cache.computeIfAbsent(Tuple.of(t1, t2, t3, t4, t5, t6), t -> Try.of(() -> tupled.apply(t)).get());
}
};
}
}

Expand Down
11 changes: 8 additions & 3 deletions src-gen/main/java/javaslang/CheckedFunction7.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
G E N E R A T O R C R A F T E D
\*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import javaslang.control.Try;

/**
Expand Down Expand Up @@ -257,9 +257,14 @@ default CheckedFunction7<T1, T2, T3, T4, T5, T6, T7, R> memoized() {
if (this instanceof Memoized) {
return this;
} else {
final Map<Tuple7<T1, T2, T3, T4, T5, T6, T7>, R> cache = new ConcurrentHashMap<>();
final Object lock = new Object();
final Map<Tuple7<T1, T2, T3, T4, T5, T6, T7>, R> cache = new HashMap<>();
final CheckedFunction1<Tuple7<T1, T2, T3, T4, T5, T6, T7>, R> tupled = tupled();
return (CheckedFunction7<T1, T2, T3, T4, T5, T6, T7, R> & Memoized) (t1, t2, t3, t4, t5, t6, t7) -> cache.computeIfAbsent(Tuple.of(t1, t2, t3, t4, t5, t6, t7), t -> Try.of(() -> tupled.apply(t)).get());
return (CheckedFunction7<T1, T2, T3, T4, T5, T6, T7, R> & Memoized) (t1, t2, t3, t4, t5, t6, t7) -> {
synchronized (lock) {
return cache.computeIfAbsent(Tuple.of(t1, t2, t3, t4, t5, t6, t7), t -> Try.of(() -> tupled.apply(t)).get());
}
};
}
}

Expand Down
11 changes: 8 additions & 3 deletions src-gen/main/java/javaslang/CheckedFunction8.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
G E N E R A T O R C R A F T E D
\*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import javaslang.control.Try;

/**
Expand Down Expand Up @@ -282,9 +282,14 @@ default CheckedFunction8<T1, T2, T3, T4, T5, T6, T7, T8, R> memoized() {
if (this instanceof Memoized) {
return this;
} else {
final Map<Tuple8<T1, T2, T3, T4, T5, T6, T7, T8>, R> cache = new ConcurrentHashMap<>();
final Object lock = new Object();
final Map<Tuple8<T1, T2, T3, T4, T5, T6, T7, T8>, R> cache = new HashMap<>();
final CheckedFunction1<Tuple8<T1, T2, T3, T4, T5, T6, T7, T8>, R> tupled = tupled();
return (CheckedFunction8<T1, T2, T3, T4, T5, T6, T7, T8, R> & Memoized) (t1, t2, t3, t4, t5, t6, t7, t8) -> cache.computeIfAbsent(Tuple.of(t1, t2, t3, t4, t5, t6, t7, t8), t -> Try.of(() -> tupled.apply(t)).get());
return (CheckedFunction8<T1, T2, T3, T4, T5, T6, T7, T8, R> & Memoized) (t1, t2, t3, t4, t5, t6, t7, t8) -> {
synchronized (lock) {
return cache.computeIfAbsent(Tuple.of(t1, t2, t3, t4, t5, t6, t7, t8), t -> Try.of(() -> tupled.apply(t)).get());
}
};
}
}

Expand Down
15 changes: 12 additions & 3 deletions src-gen/main/java/javaslang/Function1.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
G E N E R A T O R C R A F T E D
\*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;

/**
Expand Down Expand Up @@ -139,8 +139,17 @@ default Function1<T1, R> memoized() {
return this;
} else {
final Lazy<R> forNull = Lazy.of(() -> apply(null));
final Map<T1, R> cache = new ConcurrentHashMap<>();
return (Function1<T1, R> & Memoized) t1 -> (t1 == null) ? forNull.get() : cache.computeIfAbsent(t1, this::apply);
final Object lock = new Object();
final Map<T1, R> cache = new HashMap<>();
return (Function1<T1, R> & Memoized) t1 -> {
if (t1 == null) {
return forNull.get();
} else {
synchronized (lock) {
return cache.computeIfAbsent(t1, this::apply);
}
}
};
}
}

Expand Down
11 changes: 8 additions & 3 deletions src-gen/main/java/javaslang/Function2.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
G E N E R A T O R C R A F T E D
\*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiFunction;

/**
Expand Down Expand Up @@ -147,9 +147,14 @@ default Function2<T1, T2, R> memoized() {
if (this instanceof Memoized) {
return this;
} else {
final Map<Tuple2<T1, T2>, R> cache = new ConcurrentHashMap<>();
final Object lock = new Object();
final Map<Tuple2<T1, T2>, R> cache = new HashMap<>();
final Function1<Tuple2<T1, T2>, R> tupled = tupled();
return (Function2<T1, T2, R> & Memoized) (t1, t2) -> cache.computeIfAbsent(Tuple.of(t1, t2), tupled::apply);
return (Function2<T1, T2, R> & Memoized) (t1, t2) -> {
synchronized (lock) {
return cache.computeIfAbsent(Tuple.of(t1, t2), tupled::apply);
}
};
}
}

Expand Down
11 changes: 8 additions & 3 deletions src-gen/main/java/javaslang/Function3.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
G E N E R A T O R C R A F T E D
\*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

/**
* Represents a function with three arguments.
Expand Down Expand Up @@ -166,9 +166,14 @@ default Function3<T1, T2, T3, R> memoized() {
if (this instanceof Memoized) {
return this;
} else {
final Map<Tuple3<T1, T2, T3>, R> cache = new ConcurrentHashMap<>();
final Object lock = new Object();
final Map<Tuple3<T1, T2, T3>, R> cache = new HashMap<>();
final Function1<Tuple3<T1, T2, T3>, R> tupled = tupled();
return (Function3<T1, T2, T3, R> & Memoized) (t1, t2, t3) -> cache.computeIfAbsent(Tuple.of(t1, t2, t3), tupled::apply);
return (Function3<T1, T2, T3, R> & Memoized) (t1, t2, t3) -> {
synchronized (lock) {
return cache.computeIfAbsent(Tuple.of(t1, t2, t3), tupled::apply);
}
};
}
}

Expand Down
11 changes: 8 additions & 3 deletions src-gen/main/java/javaslang/Function4.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
G E N E R A T O R C R A F T E D
\*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

/**
* Represents a function with 4 arguments.
Expand Down Expand Up @@ -187,9 +187,14 @@ default Function4<T1, T2, T3, T4, R> memoized() {
if (this instanceof Memoized) {
return this;
} else {
final Map<Tuple4<T1, T2, T3, T4>, R> cache = new ConcurrentHashMap<>();
final Object lock = new Object();
final Map<Tuple4<T1, T2, T3, T4>, R> cache = new HashMap<>();
final Function1<Tuple4<T1, T2, T3, T4>, R> tupled = tupled();
return (Function4<T1, T2, T3, T4, R> & Memoized) (t1, t2, t3, t4) -> cache.computeIfAbsent(Tuple.of(t1, t2, t3, t4), tupled::apply);
return (Function4<T1, T2, T3, T4, R> & Memoized) (t1, t2, t3, t4) -> {
synchronized (lock) {
return cache.computeIfAbsent(Tuple.of(t1, t2, t3, t4), tupled::apply);
}
};
}
}

Expand Down
Loading

0 comments on commit 7b56ccd

Please sign in to comment.