fix #80
[memoization.java.git] / README.asciidoc
blobf5069aa0ae8c8f33e3dbdfe0df94b937d3f7234e
1 = memoization.java image:https://img.shields.io/badge/email-%40metio-brightgreen.svg?style=social&label=mail["Discuss on Google Groups", link="https://groups.google.com/forum/#!forum/metio"] image:https://img.shields.io/badge/irc-%23metio.wtf-brightgreen.svg?style=social&label=IRC["Chat on IRC", link="http://webchat.freenode.net/?channels=metio.wtf"]
2 Sebastian Hoß <http://seb.xn--ho-hia.de/[@sebhoss]>
3 :github-org: sebhoss
4 :project-name: memoization.java
5 :project-group: de.xn--ho-hia.memoization
6 :coverity-project: 8732
7 :codacy-project: 0ed810b7f2514f0ea1c8e86e97c803c4
8 :jdk-api: https://docs.oracle.com/javase/8/docs/api
9 :issue: https://github.com/sebhoss/memoization.java/issues
10 :toc:
11 :toc-placement: preamble
13 image:https://img.shields.io/badge/license-cc%20zero-000000.svg?style=flat-square["CC Zero", link="http://creativecommons.org/publicdomain/zero/1.0/"]
14 pass:[<span class="image"><a class="image" href="https://maven-badges.herokuapp.com/maven-central/de.xn--ho-hia.memoization/memoization.java"><img src="https://img.shields.io/maven-central/v/de.xn--ho-hia.memoization/memoization.java.svg?style=flat-square" alt="Maven Central"></a></span>]
15 image:https://reposs.herokuapp.com/?path={github-org}/{project-name}&style=flat-square["Repository size"]
16 image:https://www.openhub.net/p/memoization-java/widgets/project_thin_badge?format=gif["Open Hub statistics", link="https://www.openhub.net/p/memoization-java"]
18 image:https://img.shields.io/travis/{github-org}/{project-name}/master.svg?style=flat-square["Build Status", link="https://travis-ci.org/{github-org}/{project-name}"]
19 image:https://img.shields.io/coveralls/{github-org}/{project-name}/master.svg?style=flat-square["Code Coverage", link="https://coveralls.io/github/{github-org}/{project-name}"]
20 image:https://img.shields.io/coverity/scan/{coverity-project}.svg?style=flat-square["Coverity Scan Result", link="https://scan.coverity.com/projects/{github-org}-memoization-java"]
21 image:https://img.shields.io/codacy/grade/{codacy-project}.svg?style=flat-square["Codacy Code Quality", link="https://www.codacy.com/app/mail_7/memoization-java"]
22 image:https://img.shields.io/badge/forkable-yes-brightgreen.svg?style=flat-square["Can this project be forked?", link="https://basicallydan.github.io/forkability/?u={github-org}&r={project-name}"]
23 image:https://img.shields.io/maintenance/yes/2016.svg?style=flat-square["Is this thing still maintained?"]
24 image:https://img.shields.io/bountysource/team/metio/activity.svg?style=flat-square["Bounties on open tickets", link="https://www.bountysource.com/teams/metio"]
26 _Java link:https://en.wikipedia.org/wiki/Memoization[memoization] library - trade space for time_
28 == Features
30 * Memoize calls to `Consumer`, `Function`, `Predicate`, `Supplier` and other functional interfaces in `java.util.function`
31 * Cache values using link:https://github.com/ben-manes/caffeine[Caffeine], link:https://github.com/google/guava/wiki/CachesExplained[Guava], link:https://jcp.org/en/jsr/detail?id=107[JCache] or link:{jdk-api}/java/util/concurrent/ConcurrentMap.html[`ConcurrentMap`]
32 * Customize cache key calculation
34 .Coverage of `java.util.function`
35 |===
36 | | Caffeine | Guava | JCache | ConcurrentMap
38 | link:{jdk-api}/java/util/function/BiConsumer.html[BiConsumer]
39 | ✓
40 | ✓
41 | ✓
42 | ✓
44 | link:{jdk-api}/java/util/function/BiFunction.html[BiFunction]
45 | ✓
46 | ✓
47 | ✓
48 | ✓
50 | link:{jdk-api}/java/util/function/BiPredicate.html[BiPredicate]
51 | ✓
52 | ✓
53 | ✓
54 | ✓
56 | link:{jdk-api}/java/util/function/BooleanSupplier.html[BooleanSupplier]
57 | ✓
58 | ✓
59 | ✓
60 | ✓
62 | link:{jdk-api}/java/util/function/Consumer.html[Consumer]
63 | ✓
64 | ✓
65 | ✓
66 | ✓
68 | link:{jdk-api}/java/util/function/DoubleBinaryOperator.html[DoubleBinaryOperator]
69 | ✓
70 | ✓
71 | ✓
72 | ✓
74 | link:{jdk-api}/java/util/function/DoubleConsumer.html[DoubleConsumer]
75 | ✓
76 | ✓
77 | ✓
78 | ✓
80 | link:{jdk-api}/java/util/function/DoubleFunction.html[DoubleFunction]
81 | ✓
82 | ✓
83 | ✓
84 | ✓
86 | link:{jdk-api}/java/util/function/DoublePredicate.html[DoublePredicate]
87 | ✓
88 | ✓
89 | ✓
90 | ✓
92 | link:{jdk-api}/java/util/function/DoubleSupplier.html[DoubleSupplier]
93 | ✓
94 | ✓
95 | ✓
96 | ✓
98 | link:{jdk-api}/java/util/function/DoubleToIntFunction.html[DoubleToIntFunction]
99 | ✓
100 | ✓
101 | link:{issue}/133[#133]
102 | ✓
104 | link:{jdk-api}/java/util/function/DoubleToLongFunction.html[DoubleToLongFunction]
105 | ✓
106 | ✓
107 | link:{issue}/134[#134]
108 | ✓
110 | link:{jdk-api}/java/util/function/DoubleUnaryOperator.html[DoubleUnaryOperator]
111 | ✓
112 | ✓
113 | link:{issue}/135[#135]
114 | ✓
116 | link:{jdk-api}/java/util/function/Function.html[Function]
117 | ✓
118 | ✓
119 | ✓
120 | ✓
122 | link:{jdk-api}/java/util/function/IntBinaryOperator.html[IntBinaryOperator]
123 | ✓
124 | ✓
125 | ✓
126 | ✓
128 | link:{jdk-api}/java/util/function/IntConsumer.html[IntConsumer]
129 | ✓
130 | ✓
131 | ✓
132 | ✓
134 | link:{jdk-api}/java/util/function/IntFunction.html[IntFunction]
135 | ✓
136 | ✓
137 | ✓
138 | ✓
140 | link:{jdk-api}/java/util/function/IntPredicate.html[IntPredicate]
141 | ✓
142 | ✓
143 | ✓
144 | ✓
146 | link:{jdk-api}/java/util/function/IntSupplier.html[IntSupplier]
147 | ✓
148 | ✓
149 | ✓
150 | ✓
152 | link:{jdk-api}/java/util/function/IntToDoubleFunction.html[IntToDoubleFunction]
153 | ✓
154 | ✓
155 | link:{issue}/140[#140]
156 | ✓
158 | link:{jdk-api}/java/util/function/IntToLongFunction.html[IntToLongFunction]
159 | ✓
160 | ✓
161 | link:{issue}/141[#141]
162 | ✓
164 | link:{jdk-api}/java/util/function/IntUnaryOperator.html[IntUnaryOperator]
165 | ✓
166 | ✓
167 | link:{issue}/142[#142]
168 | ✓
170 | link:{jdk-api}/java/util/function/LongBinaryOperator.html[LongBinaryOperator]
171 | ✓
172 | ✓
173 | ✓
174 | ✓
176 | link:{jdk-api}/java/util/function/LongConsumer.html[LongConsumer]
177 | ✓
178 | ✓
179 | ✓
180 | ✓
182 | link:{jdk-api}/java/util/function/LongFunction.html[LongFunction]
183 | ✓
184 | ✓
185 | ✓
186 | ✓
188 | link:{jdk-api}/java/util/function/LongPredicate.html[LongPredicate]
189 | ✓
190 | ✓
191 | ✓
192 | ✓
194 | link:{jdk-api}/java/util/function/LongSupplier.html[LongSupplier]
195 | ✓
196 | ✓
197 | ✓
198 | ✓
200 | link:{jdk-api}/java/util/function/LongToDoubleFunction.html[LongToDoubleFunction]
201 | ✓
202 | ✓
203 | link:{issue}/147[#147]
204 | ✓
206 | link:{jdk-api}/java/util/function/LongToIntFunction.html[LongToIntFunction]
207 | ✓
208 | ✓
209 | link:{issue}/148[#148]
210 | ✓
212 | link:{jdk-api}/java/util/function/LongUnaryOperator.html[LongUnaryOperator]
213 | ✓
214 | ✓
215 | link:{issue}/149[#149]
216 | ✓
218 | link:{jdk-api}/java/util/function/ObjDoubleConsumer.html[ObjDoubleConsumer]
219 | ✓
220 | ✓
221 | link:{issue}/150[#150]
222 | ✓
224 | link:{jdk-api}/java/util/function/ObjIntConsumer.html[ObjIntConsumer]
225 | ✓
226 | ✓
227 | link:{issue}/151[#151]
228 | ✓
230 | link:{jdk-api}/java/util/function/ObjLongConsumer.html[ObjLongConsumer]
231 | ✓
232 | ✓
233 | link:{issue}/152[#152]
234 | ✓
236 | link:{jdk-api}/java/util/function/Predicate.html[Predicate]
237 | ✓
238 | ✓
239 | ✓
240 | ✓
242 | link:{jdk-api}/java/util/function/Supplier.html[Supplier]
243 | ✓
244 | ✓
245 | ✓
246 | ✓
248 | link:{jdk-api}/java/util/function/ToDoubleBiFunction.html[ToDoubleBiFunction]
249 | ✓
250 | ✓
251 | link:{issue}/154[#154]
252 | ✓
254 | link:{jdk-api}/java/util/function/ToDoubleFunction.html[ToDoubleFunction]
255 | ✓
256 | ✓
257 | link:{issue}/157[#157]
258 | ✓
260 | link:{jdk-api}/java/util/function/ToIntBiFunction.html[ToIntBiFunction]
261 | ✓
262 | ✓
263 | link:{issue}/155[#155]
264 | ✓
266 | link:{jdk-api}/java/util/function/ToIntFunction.html[ToIntFunction]
267 | ✓
268 | ✓
269 | link:{issue}/158[#158]
270 | ✓
272 | link:{jdk-api}/java/util/function/ToLongBiFunction.html[ToLongBiFunction]
273 | ✓
274 | ✓
275 | link:{issue}/156[#156]
276 | ✓
278 | link:{jdk-api}/java/util/function/ToLongFunction.html[ToLongFunction]
279 | ✓
280 | ✓
281 | link:{issue}/159[#159]
282 | ✓
283 |===
286 == Development Status
288 The Caffeine, Guava and `ConcurrentMap` based implementations cover all functional interfaces from `java.util.function`, the JCache module is currently in progress. Take a look at the link:https://github.com/sebhoss/memoization.java/issues[open tickets].
290 == Usage
292 Memoize any of the supported types by using the static factory methods supplied by either using `CaffeineMemoize` pass:[<span class="image"><a class="image" href="https://www.javadoc.io/doc/de.xn--ho-hia.memoization/memoization-caffeine"><img src="https://www.javadoc.io/badge/de.xn--ho-hia.memoization/memoization-caffeine.svg?style=flat-square&color=blue" alt="Read JavaDocs"></a></span>], `GuavaMemoize` pass:[<span class="image"><a class="image" href="https://www.javadoc.io/doc/de.xn--ho-hia.memoization/memoization-guava"><img src="https://www.javadoc.io/badge/de.xn--ho-hia.memoization/memoization-guava.svg?style=flat-square&color=blue" alt="Read JavaDocs"></a></span>], `JCacheMemoize` pass:[<span class="image"><a class="image" href="https://www.javadoc.io/doc/de.xn--ho-hia.memoization/memoization-jcache"><img src="https://www.javadoc.io/badge/de.xn--ho-hia.memoization/memoization-jcache.svg?style=flat-square&color=blue" alt="Read JavaDocs"></a></span>] or `MapMemoize` pass:[<span class="image"><a class="image" href="https://www.javadoc.io/doc/de.xn--ho-hia.memoization/memoization-core"><img src="https://www.javadoc.io/badge/de.xn--ho-hia.memoization/memoization-core.svg?style=flat-square&color=blue" alt="Read JavaDocs"></a></span>] like this:
294 === Default cache w/ default cache keys
296 [source, java]
297 ----
298 // memoize in Caffeine cache
299 Consumer<INPUT> consumer                 = ...;
300 Consumer<INPUT> memoizedConsumer         = CaffeineMemoize.consumer(consumer);
302 // memoize in Guava cache
303 Function<INPUT, OUTPUT> function         = ...;
304 Function<INPUT, OUTPUT> memoizedFunction = GuavaMemoize.function(function);
306 // memoize in JCache cache
307 Predicate<INPUT> predicate               = ...;
308 Predicate<INPUT> memoizedPredicate       = JCacheMemoize.predicate(predicate);
310 // memoize in ConcurrentMap
311 Supplier<OUTPUT> supplier                = ...;
312 Supplier<OUTPUT> memoizedSupplier        = MapMemoize.supplier(supplier);
313 ----
315 === Default cache w/ custom cache keys
317 [source, java]
318 ----
319 // memoize in Caffeine cache
320 Consumer<INPUT> consumer                 = ...;
321 Function<INPUT, KEY> keyFunction         = ...;
322 Consumer<INPUT> memoizedConsumer         = CaffeineMemoize.consumer(consumer, keyFunction);
324 // memoize in Guava cache
325 Function<INPUT, OUTPUT> function         = ...;
326 Function<INPUT, KEY> keyFunction         = ...;
327 Function<INPUT, OUTPUT> memoizedFunction = GuavaMemoize.function(function, keyFunction);
329 // memoize in JCache cache
330 Predicate<INPUT> predicate               = ...;
331 Function<INPUT, KEY> keyFunction         = ...;
332 Predicate<INPUT> memoizedPredicate       = JCacheMemoize.predicate(predicate, keyFunction);
334 // memoize in ConcurrentMap
335 Supplier<OUTPUT> supplier                = ...;
336 Supplier<KEY> keySupplier                = ...;
337 Supplier<OUTPUT> memoizedSupplier        = MapMemoize.supplier(supplier, keySupplier);
338 ----
340 === Custom cache w/ default cache keys
342 [source, java]
343 ----
344 // memoize in Caffeine cache
345 Consumer<INPUT> consumer                 = ...;
346 Cache<INPUT, INPUT> cache                = ...; // com.github.benmanes.caffeine.cache.Cache
347 Consumer<INPUT> memoizedConsumer         = CaffeineMemoize.consumer(consumer, cache);
349 // memoize in Guava cache
350 Function<INPUT, OUTPUT> function         = ...;
351 Cache<INPUT, OUTPUT> cache               = ...; // com.google.common.cache.Cache
352 Function<INPUT, OUTPUT> memoizedFunction = GuavaMemoize.function(function, cache);
354 // memoize in JCache cache
355 Predicate<INPUT> predicate               = ...;
356 Cache<INPUT, Boolean> cache              = ...; // javax.cache.Cache
357 Predicate<INPUT> memoizedPredicate       = JCacheMemoize.predicate(predicate, cache);
359 // memoize in ConcurrentMap
360 Supplier<OUTPUT> supplier                = ...;
361 Map<String, OUTPUT> cache                = ...;
362 Supplier<OUTPUT> memoizedSupplier        = MapMemoize.supplier(supplier, cache);
363 ----
365 === Custom cache w/ custom cache keys
367 [source, java]
368 ----
369 // memoize in Caffeine cache
370 Consumer<INPUT> consumer                 = ...;
371 Function<INPUT, KEY> keyFunction         = ...;
372 Cache<KEY, INPUT> cache                  = ...; // com.github.benmanes.caffeine.cache.Cache
373 Consumer<INPUT> memoizedConsumer         = CaffeineMemoize.consumer(consumer, keyFunction, cache);
375 // memoize in Guava cache
376 Function<INPUT, OUTPUT> function         = ...;
377 Function<INPUT, KEY> keyFunction         = ...;
378 Cache<KEY, OUTPUT> cache                 = ...; // com.google.common.cache.Cache
379 Function<INPUT, OUTPUT> memoizedFunction = GuavaMemoize.function(function, keyFunction, cache);
381 // memoize in JCache cache
382 Predicate<INPUT> predicate               = ...;
383 Function<INPUT, KEY> keyFunction         = ...;
384 Cache<KEY, Boolean> cache                = ...; // javax.cache.Cache
385 Predicate<INPUT> memoizedPredicate       = JCacheMemoize.predicate(predicate, keyFunction, cache);
387 // memoize in ConcurrentMap
388 Supplier<OUTPUT> supplier                = ...;
389 Supplier<KEY> keySupplier                = ...;
390 Map<KEY, OUTPUT> cache                   = ...;
391 Supplier<OUTPUT> memoizedSupplier        = MapMemoize.supplier(supplier, keySupplier, cache);
392 ----
394 === Integration
396 In order to use this project, declare the following inside your POM:
398 [source, xml, subs="attributes,verbatim"]
399 ----
400 <dependencies>
401   <dependency>
402     <groupId>{project-group}</groupId>
403     <artifactId>memoization-core</artifactId>
404     <version>${version.memoization}</version>
405   </dependency>
407   <!-- CAFFEINE ONLY -->
408   <dependency>
409     <groupId>{project-group}</groupId>
410     <artifactId>memoization-caffeine</artifactId>
411     <version>${version.memoization}</version>
412   </dependency>
413   <dependency>
414     <groupId>com.github.ben-manes.caffeine</groupId>
415     <artifactId>caffeine</artifactId>
416     <version>${version.caffeine}</version>
417   </dependency>
418   <!-- CAFFEINE ONLY -->
420   <!-- GUAVA ONLY -->
421   <dependency>
422     <groupId>{project-group}</groupId>
423     <artifactId>memoization-guava</artifactId>
424     <version>${version.memoization}</version>
425   </dependency>
426   <dependency>
427     <groupId>com.google.guava</groupId>
428     <artifactId>guava</artifactId>
429     <version>${version.guava}</version>
430   </dependency>
431   <!-- GUAVA ONLY -->
433   <!-- JCACHE ONLY -->
434   <dependency>
435     <groupId>{project-group}</groupId>
436     <artifactId>memoization-jcache</artifactId>
437     <version>${version.memoization}</version>
438   </dependency>
439   <dependency>
440     <groupId>javax.cache</groupId>
441     <artifactId>cache-api</artifactId>
442     <version>${version.jcache}</version>
443   </dependency>
444   <!-- Add your JCache implementation here -->
445   <dependency>
446     <groupId>...</groupId>
447     <artifactId>...</artifactId>
448     <version>...</version>
449   </dependency>
450   <!-- JCACHE ONLY -->
452 </dependencies>
453 ----
455 Replace `${version.memoization}` with the pass:[<a href="https://search.maven.org/#search%7Cga%7C1%7Cg%3Ade.xn--ho-hia.memoization">latest release</a>]. This project follows the link:http://semver.org/[semantic versioning guidelines].
457 === Compatibility
459 This project is compatible with the following Java versions:
461 .Java compatibility
462 |===
463 | | 1.X.Y | 2.X.Y
465 | Java 8
466 | ✓
467 | ✓
468 |===
470 == Alternatives
472 * link:http://www.tek271.com/software/java/memoizer[Tek271 Memoizer]
473 * link:https://github.com/kelvinguu/gitmemoizer[GitMemoizer]
474 * link:http://docs.spring.io/spring/docs/current/spring-framework-reference/html/cache.html#cache-annotations-cacheable[Spring's `@Cacheable`]
475 * link:https://github.com/marmelo/chili#memoize[Chili's `@Memoize`]
476 * link:https://clojuredocs.org/clojure.core/memoize[Clojure's `(memoize f)`]
477 * link:http://docs.groovy-lang.org/latest/html/gapi/groovy/transform/Memoized.html[Groovy's `@Memoized`]
478 * link:https://github.com/cb372/scalacache#memoization-of-method-results[ScalaCache's `memoize`]
480 == License
482 To the extent possible under law, the author(s) have dedicated all copyright
483 and related and neighboring rights to this software to the public domain
484 worldwide. This software is distributed without any warranty.
486 You should have received a copy of the CC0 Public Domain Dedication along
487 with this software. If not, see http://creativecommons.org/publicdomain/zero/1.0/.
489 == Mirrors
491 * https://github.com/sebhoss/memoization.java
492 * https://bitbucket.org/sebhoss/memoization.java
493 * https://gitlab.com/sebastian.hoss/memoization.java
494 * http://v2.pikacode.com/sebhoss/memoization.java
495 * http://repo.or.cz/memoization.java.git