1 /** 2 Copyright: Copyright (c) 2019, Joakim Brännström. All rights reserved. 3 License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0) 4 Author: Joakim Brännström (joakim.brannstrom@gmx.com) 5 6 Based on require in `object.d` in druntime therefor the Boost license. 7 8 A convenient function extending cachetools with a common recurring function. 9 */ 10 module dextool.cachetools; 11 12 import std.datetime : Duration; 13 14 import my.from_; 15 16 /*********************************** 17 * Looks up key; if it exists returns corresponding value else evaluates 18 * value, adds it to the associative array and returns it. 19 * Params: 20 * aa = The cache. 21 * key = The key. 22 * value = The required value. 23 * Returns: 24 * The value. 25 * 26 * Example: 27 * --- 28 * auto cache = CacheLRU!(int,string); 29 * cache.require(5, { return "5"; }()); 30 * --- 31 */ 32 //TODO: rename to require when the workaround for <2.082 compiles is removed. 33 V cacheToolsRequire(CT, K, V)(CT aa, K key, lazy V value = V.init) 34 if (is(CT == class) && !is(CT == V[K])) { 35 // TODO: when upgrading to a 2.082+ compiler use this constraint instead 36 //if (is(CT == from!"cachetools".CacheLRU!(K, V))) { 37 auto q = aa.get(key); 38 if (q.isNull) { 39 auto v = value; 40 aa.put(key, v); 41 return v; 42 } 43 return q.get; 44 } 45 46 // TODO: remove this when upgrading the minimal compiler. 47 static if (__VERSION__ < 2082L) { 48 /*********************************** 49 * Looks up key; if it exists returns corresponding value else evaluates 50 * value, adds it to the associative array and returns it. 51 * Params: 52 * aa = The associative array. 53 * key = The key. 54 * value = The required value. 55 * Returns: 56 * The value. 57 */ 58 ref V require(K, V)(ref V[K] aa, K key, lazy V value = V.init) @trusted { 59 if (auto v = key in aa) { 60 return *v; 61 } 62 63 aa[key] = value; 64 return aa[key]; 65 } 66 } 67 68 struct NullableCache(K, V, alias getValue) { 69 import std.typecons : Nullable; 70 import cachetools : CacheLRU; 71 72 CacheLRU!(K, V) cache; 73 74 this(CacheLRU!(K, V) cache, int size = 0, Duration ttl = Duration.zero) { 75 this.cache = cache; 76 if (size != 0) 77 cache.size = size; 78 if (ttl != Duration.zero) 79 cache.ttl = ttl; 80 } 81 82 static if (__VERSION__ > 2089L) { 83 ~this() { 84 .destroy(cache); 85 } 86 } 87 88 auto get(K k) { 89 Nullable!V rval = cache.get(k); 90 if (rval.isNull) { 91 rval = getValue(k); 92 if (!rval.isNull) { 93 cache.put(k, rval.get); 94 } 95 } 96 return rval; 97 } 98 99 auto opCall(K k) { 100 return get(k); 101 } 102 } 103 104 auto nullableCache(K, V, alias getValue)(int size = 0, Duration ttl = Duration.zero) { 105 import cachetools : CacheLRU; 106 107 return NullableCache!(K, V, getValue)(new CacheLRU!(K, V)); 108 }