MCPcopy Create free account
hub / github.com/traneio/future / Tailrec

Class Tailrec

future-java/src/main/java/io/trane/future/Tailrec.java:56–125  ·  view source on GitHub ↗

`Tailrec` e ensures that recursive futures are stack-safe. Given the optimization that this library implements to avoid thread context switch, compositions are not stack-safe by default. It is necessary to wrap recursive computations with a `Tailrec` call: ```java public Future factorial(

Source from the content-addressed store, hash-verified

54 * increase the risk of a `StackOverflowException`.
55 */
56public final class Tailrec {
57
58 private static final int DEFAULT_BATCH_SIZE = Optional
59 .ofNullable(System.getProperty("io.trane.future.defaultBatchSize")).map(Integer::parseInt).orElse(512);
60
61 private static final ThreadLocal<Tailrec> local = new ThreadLocal<Tailrec>() {
62 @Override
63 public Tailrec initialValue() {
64 return new Tailrec();
65 }
66 };
67
68 private ArrayList<Runnable> tasks = null;
69 private int syncPermits = 0;
70
71 private boolean running = false;
72
73 private final boolean runSync() {
74 return syncPermits-- > 0;
75 }
76
77 private final void submit(final Runnable r, final int batchSize) {
78 syncPermits = batchSize;
79 tasks = new ArrayList<>(1);
80 tasks.add(r);
81 if (!running) {
82 run();
83 syncPermits = 0;
84 }
85 }
86
87 private final void run() {
88 running = true;
89 while (tasks != null) {
90 final ArrayList<Runnable> pending = tasks;
91 tasks = null;
92 for (int i = 0; i < pending.size(); i++)
93 pending.get(i).run();
94 }
95 running = false;
96 }
97
98 /**
99 * Runs the recursive future using the default batch size.
100 *
101 * @param sup the supplier to be called on each recursion.
102 * @return the stack-safe recursive future.
103 */
104 public static final <T> Future<T> apply(final Supplier<Future<T>> sup) {
105 return apply(DEFAULT_BATCH_SIZE, sup);
106 }
107
108 /**
109 * Runs the recursive future using the custom batch size.
110 *
111 * @param batchSize the custom batch size.
112 * @param sup the supplier to be called on each recursion.
113 * @return the stack-safe recursive future.

Callers

nothing calls this directly

Calls 1

mapMethod · 0.65

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…