1 people like it.

Thread-safe Generic MemoryCache and Memoize Function

A generic, thread-safe version of a MemoryCache based on ConcurrentDictionary, and a memoize function implemented using the MemoryCache.

  1: 
  2: 
  3: 
  4: 
  5: 
  6: 
  7: 
  8: 
  9: 
 10: 
 11: 
 12: 
 13: 
 14: 
 15: 
 16: 
 17: 
 18: 
 19: 
 20: 
 21: 
 22: 
 23: 
 24: 
 25: 
 26: 
 27: 
 28: 
 29: 
 30: 
 31: 
 32: 
 33: 
 34: 
 35: 
 36: 
 37: 
 38: 
 39: 
 40: 
 41: 
 42: 
 43: 
 44: 
 45: 
 46: 
 47: 
 48: 
 49: 
 50: 
 51: 
 52: 
 53: 
 54: 
 55: 
 56: 
 57: 
 58: 
 59: 
 60: 
 61: 
 62: 
 63: 
 64: 
 65: 
 66: 
 67: 
 68: 
 69: 
 70: 
 71: 
 72: 
 73: 
 74: 
 75: 
 76: 
 77: 
 78: 
 79: 
 80: 
 81: 
 82: 
 83: 
 84: 
 85: 
 86: 
 87: 
 88: 
 89: 
 90: 
 91: 
 92: 
 93: 
 94: 
 95: 
 96: 
 97: 
 98: 
 99: 
100: 
101: 
102: 
103: 
104: 
105: 
106: 
107: 
108: 
109: 
110: 
111: 
112: 
113: 
114: 
115: 
116: 
117: 
118: 
119: 
120: 
121: 
122: 
123: 
124: 
125: 
126: 
127: 
128: 
129: 
130: 
131: 
132: 
133: 
134: 
135: 
136: 
137: 
138: 
139: 
140: 
141: 
142: 
143: 
144: 
145: 
146: 
147: 
148: 
149: 
150: 
151: 
152: 
153: 
154: 
155: 
156: 
157: 
158: 
159: 
160: 
161: 
162: 
163: 
164: 
165: 
166: 
open System
open System.Collections.Concurrent
open System.Collections.Generic
open System.Timers

type CacheExpirationPolicy =
| NoExpiration
| AbsoluteExpiration of TimeSpan
| SlidingExpiration of TimeSpan

type CacheEntryExpiration =
| NeverExpires
| ExpiresAt of DateTime
| ExpiresAfter of TimeSpan

type CacheEntry<'key, 'value> =
    {
        Key: 'key
        Value: 'value
        Expiration: CacheEntryExpiration
        LastUsage: DateTime
    }

module CacheExpiration =
    let isExpired (entry: CacheEntry<_,_>) =
        match entry.Expiration with
        | NeverExpires -> false
        | ExpiresAt date -> DateTime.UtcNow > date
        | ExpiresAfter window -> (DateTime.UtcNow - entry.LastUsage) > window

type private IMemoryCacheStore<'key, 'value> =
    inherit IEnumerable<CacheEntry<'key, 'value>>
    abstract member Add: CacheEntry<'key, 'value> -> unit
    abstract member GetOrAdd: 'key -> ('key -> CacheEntry<'key, 'value>) -> CacheEntry<'key, 'value>
    abstract member Remove: 'key -> unit
    abstract member Contains: 'key -> bool
    abstract member Update: 'key -> (CacheEntry<'key, 'value> -> CacheEntry<'key, 'value>) -> unit
    abstract member TryFind: 'key -> CacheEntry<'key, 'value> option

type MemoryCache<'key, 'value> (?cacheExpirationPolicy) =
    let policy = defaultArg cacheExpirationPolicy NoExpiration
    let store = 
        let entries = ConcurrentDictionary<'key, CacheEntry<'key, 'value>>()
        let get, getEnumerator =
            let values = entries |> Seq.map (fun kvp -> kvp.Value)
            (fun () -> values), (fun () -> values.GetEnumerator())
        {new IMemoryCacheStore<'key, 'value> with
            member __.Add entry = entries.AddOrUpdate(entry.Key, entry, fun _ _ -> entry) |> ignore
            member __.GetOrAdd key getValue = entries.GetOrAdd(key, getValue)
            member __.Remove key = entries.TryRemove key |> ignore
            member __.Contains key = entries.ContainsKey key
            member __.Update key update = 
                match entries.TryGetValue(key) with
                | (true, entry) -> entries.AddOrUpdate(key, entry, fun _ entry -> update entry) |> ignore
                | _ -> ()
            member __.TryFind key =
                match entries.TryGetValue(key) with
                | (true, entry) -> Some entry
                | _ -> None
            member __.GetEnumerator () = getEnumerator ()
            member __.GetEnumerator () = getEnumerator () :> Collections.IEnumerator
        }
    
    let checkExpiration () =
        store 
        |> Seq.filter CacheExpiration.isExpired
        |> Seq.map (fun entry -> entry.Key)
        |> Seq.iter store.Remove

    let newCacheEntry key value =
        { Key = key
          Value = value
          Expiration = match policy with
                       | NoExpiration -> NeverExpires
                       | AbsoluteExpiration time -> ExpiresAt (DateTime.UtcNow + time)
                       | SlidingExpiration window -> ExpiresAfter window
          LastUsage = DateTime.UtcNow
        }

    let add key value =
        if key |> store.Contains
        then store.Update key (fun entry -> {entry with Value = value; LastUsage = DateTime.UtcNow})
        else store.Add <| newCacheEntry key value

    let remove key = 
        store.Remove key

    let get key =
        store.TryFind key |> Option.bind (fun entry -> Some entry.Value)

    let getOrAdd key value = 
        store.GetOrAdd key (fun _ -> newCacheEntry key value) 
        |> fun entry -> entry.Value

    let getOrAddResult key f =
        store.GetOrAdd key (fun _ -> newCacheEntry key <| f())
        |> fun entry -> entry.Value

    let getTimer (expiration: TimeSpan) =
        if expiration.TotalSeconds < 1.0
        then TimeSpan.FromMilliseconds 100.0
        elif expiration.TotalMinutes < 1.0 
        then TimeSpan.FromSeconds 1.0 
        else TimeSpan.FromMinutes 1.0
        |> fun interval -> new Timer(interval.TotalMilliseconds)

    let timer = 
       match policy with
       | NoExpiration -> None
       | AbsoluteExpiration time -> time |> getTimer |> Some
       | SlidingExpiration time -> time |> getTimer |> Some    

    let observer =
        match timer with
        | Some t -> 
            let disposable = t.Elapsed |> Observable.subscribe (fun _ -> checkExpiration())
            t.Start()
            Some disposable
        | None -> None

    member __.Add key value = add key value
    member __.Remove key = remove key
    member __.Get key = get key
    member __.GetOrAdd key value = getOrAdd key value    
    member __.GetOrAddResult key f = getOrAddResult key f

[<AutoOpen>]
module Memoization =
    type private MemoizationCache<'a,'b when 'a: equality> (?cacheExpirationPolicy) =
        let cache = 
            match cacheExpirationPolicy with
            | Some policy -> new MemoryCache<string,'b>(policy)
            | None -> new MemoryCache<string,'b>()
        let getKey (key: 'a) = 
            if key |> box |> isNull
            then typeof<'a>.FullName
            else sprintf "%s_%d" typeof<'a>.FullName <| key.GetHashCode()
        member __.TryGetValue key =
            let keyString = getKey key
            cache.Get keyString
        member __.GetOrAdd key getValue =
            let keyString = getKey key
            cache.GetOrAddResult keyString getValue

    let private memoizeWithCache f (cache: MemoizationCache<_,_>) x =
        (fun () -> f x) |> cache.GetOrAdd x            

    /// Create a new function that remembers the results of the given function
    /// for each unique input parameter, returning the cached result instead
    /// of recomputing it each time the function is called, optimizing the execution speed
    /// at the cost of increased memory usage.
    ///
    /// Note:  This optimization should only be used with referentially transparent functions
    let memoize f = 
        new MemoizationCache<_,_>() |> memoizeWithCache f

    /// Create a new function that remembers the results of the given function
    /// for each unique input parameter, returning the cached result instead
    /// of recomputing it each time the function is called, optimizing the execution speed
    /// at the cost of increased memory usage.  Uses a specified Cache Expiration Policy
    /// to limit the amount of time the results are stored, to allow memory to be free'd
    /// after a certain amount of time.
    ///
    /// Note:  This optimization should only be used with referentially transparent functions
    let memoizeWithExpiration policy f = 
        new MemoizationCache<_,_>(policy) |> memoizeWithCache f
namespace System
namespace System.Collections
namespace System.Collections.Concurrent
namespace System.Collections.Generic
namespace System.Timers
type CacheExpirationPolicy =
  | NoExpiration
  | AbsoluteExpiration of TimeSpan
  | SlidingExpiration of TimeSpan

Full name: Script.CacheExpirationPolicy
union case CacheExpirationPolicy.NoExpiration: CacheExpirationPolicy
union case CacheExpirationPolicy.AbsoluteExpiration: TimeSpan -> CacheExpirationPolicy
Multiple items
type TimeSpan =
  struct
    new : ticks:int64 -> TimeSpan + 3 overloads
    member Add : ts:TimeSpan -> TimeSpan
    member CompareTo : value:obj -> int + 1 overload
    member Days : int
    member Duration : unit -> TimeSpan
    member Equals : value:obj -> bool + 1 overload
    member GetHashCode : unit -> int
    member Hours : int
    member Milliseconds : int
    member Minutes : int
    ...
  end

Full name: System.TimeSpan

--------------------
TimeSpan()
TimeSpan(ticks: int64) : unit
TimeSpan(hours: int, minutes: int, seconds: int) : unit
TimeSpan(days: int, hours: int, minutes: int, seconds: int) : unit
TimeSpan(days: int, hours: int, minutes: int, seconds: int, milliseconds: int) : unit
union case CacheExpirationPolicy.SlidingExpiration: TimeSpan -> CacheExpirationPolicy
type CacheEntryExpiration =
  | NeverExpires
  | ExpiresAt of DateTime
  | ExpiresAfter of TimeSpan

Full name: Script.CacheEntryExpiration
union case CacheEntryExpiration.NeverExpires: CacheEntryExpiration
union case CacheEntryExpiration.ExpiresAt: DateTime -> CacheEntryExpiration
Multiple items
type DateTime =
  struct
    new : ticks:int64 -> DateTime + 10 overloads
    member Add : value:TimeSpan -> DateTime
    member AddDays : value:float -> DateTime
    member AddHours : value:float -> DateTime
    member AddMilliseconds : value:float -> DateTime
    member AddMinutes : value:float -> DateTime
    member AddMonths : months:int -> DateTime
    member AddSeconds : value:float -> DateTime
    member AddTicks : value:int64 -> DateTime
    member AddYears : value:int -> DateTime
    ...
  end

Full name: System.DateTime

--------------------
DateTime()
   (+0 other overloads)
DateTime(ticks: int64) : unit
   (+0 other overloads)
DateTime(ticks: int64, kind: DateTimeKind) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int, calendar: Globalization.Calendar) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, kind: DateTimeKind) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, calendar: Globalization.Calendar) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int, kind: DateTimeKind) : unit
   (+0 other overloads)
union case CacheEntryExpiration.ExpiresAfter: TimeSpan -> CacheEntryExpiration
type CacheEntry<'key,'value> =
  {Key: 'key;
   Value: 'value;
   Expiration: CacheEntryExpiration;
   LastUsage: DateTime;}

Full name: Script.CacheEntry<_,_>
CacheEntry.Key: 'key
CacheEntry.Value: 'value
CacheEntry.Expiration: CacheEntryExpiration
CacheEntry.LastUsage: DateTime
val isExpired : entry:CacheEntry<'a,'b> -> bool

Full name: Script.CacheExpiration.isExpired
val entry : CacheEntry<'a,'b>
val date : DateTime
property DateTime.UtcNow: DateTime
val window : TimeSpan
type private IMemoryCacheStore<'key,'value> =
  interface
    inherit IEnumerable<CacheEntry<'key,'value>>
    abstract member Add : CacheEntry<'key,'value> -> unit
    abstract member Contains : 'key -> bool
    abstract member GetOrAdd : 'key -> ('key -> CacheEntry<'key,'value>) -> CacheEntry<'key,'value>
    abstract member Remove : 'key -> unit
    abstract member TryFind : 'key -> CacheEntry<'key,'value> option
    abstract member Update : 'key -> (CacheEntry<'key,'value> -> CacheEntry<'key,'value>) -> unit
  end

Full name: Script.IMemoryCacheStore<_,_>
type IEnumerable<'T> =
  member GetEnumerator : unit -> IEnumerator<'T>

Full name: System.Collections.Generic.IEnumerable<_>
abstract member private IMemoryCacheStore.Add : CacheEntry<'key,'value> -> unit

Full name: Script.IMemoryCacheStore`2.Add
type unit = Unit

Full name: Microsoft.FSharp.Core.unit
abstract member private IMemoryCacheStore.GetOrAdd : 'key -> ('key -> CacheEntry<'key,'value>) -> CacheEntry<'key,'value>

Full name: Script.IMemoryCacheStore`2.GetOrAdd
abstract member private IMemoryCacheStore.Remove : 'key -> unit

Full name: Script.IMemoryCacheStore`2.Remove
abstract member private IMemoryCacheStore.Contains : 'key -> bool

Full name: Script.IMemoryCacheStore`2.Contains
type bool = Boolean

Full name: Microsoft.FSharp.Core.bool
abstract member private IMemoryCacheStore.Update : 'key -> (CacheEntry<'key,'value> -> CacheEntry<'key,'value>) -> unit

Full name: Script.IMemoryCacheStore`2.Update
abstract member private IMemoryCacheStore.TryFind : 'key -> CacheEntry<'key,'value> option

Full name: Script.IMemoryCacheStore`2.TryFind
type 'T option = Option<'T>

Full name: Microsoft.FSharp.Core.option<_>
Multiple items
type MemoryCache<'key,'value> =
  new : ?cacheExpirationPolicy:CacheExpirationPolicy -> MemoryCache<'key,'value>
  member Add : key:'key -> value:'value -> unit
  member Get : key:'key -> 'value option
  member GetOrAdd : key:'key -> value:'value -> 'value
  member GetOrAddResult : key:'key -> f:(unit -> 'value) -> 'value
  member Remove : key:'key -> unit

Full name: Script.MemoryCache<_,_>

--------------------
new : ?cacheExpirationPolicy:CacheExpirationPolicy -> MemoryCache<'key,'value>
val cacheExpirationPolicy : CacheExpirationPolicy option
val policy : CacheExpirationPolicy
val defaultArg : arg:'T option -> defaultValue:'T -> 'T

Full name: Microsoft.FSharp.Core.Operators.defaultArg
val store : IMemoryCacheStore<'key,'value>
val entries : ConcurrentDictionary<'key,CacheEntry<'key,'value>>
Multiple items
type ConcurrentDictionary<'TKey,'TValue> =
  new : unit -> ConcurrentDictionary<'TKey, 'TValue> + 6 overloads
  member AddOrUpdate : key:'TKey * addValueFactory:Func<'TKey, 'TValue> * updateValueFactory:Func<'TKey, 'TValue, 'TValue> -> 'TValue + 1 overload
  member Clear : unit -> unit
  member ContainsKey : key:'TKey -> bool
  member Count : int
  member GetEnumerator : unit -> IEnumerator<KeyValuePair<'TKey, 'TValue>>
  member GetOrAdd : key:'TKey * valueFactory:Func<'TKey, 'TValue> -> 'TValue + 1 overload
  member IsEmpty : bool
  member Item : 'TKey -> 'TValue with get, set
  member Keys : ICollection<'TKey>
  ...

Full name: System.Collections.Concurrent.ConcurrentDictionary<_,_>

--------------------
ConcurrentDictionary() : unit
ConcurrentDictionary(collection: IEnumerable<KeyValuePair<'TKey,'TValue>>) : unit
ConcurrentDictionary(comparer: IEqualityComparer<'TKey>) : unit
ConcurrentDictionary(concurrencyLevel: int, capacity: int) : unit
ConcurrentDictionary(collection: IEnumerable<KeyValuePair<'TKey,'TValue>>, comparer: IEqualityComparer<'TKey>) : unit
ConcurrentDictionary(concurrencyLevel: int, collection: IEnumerable<KeyValuePair<'TKey,'TValue>>, comparer: IEqualityComparer<'TKey>) : unit
ConcurrentDictionary(concurrencyLevel: int, capacity: int, comparer: IEqualityComparer<'TKey>) : unit
val get : (unit -> seq<CacheEntry<'key,'value>>)
val getEnumerator : (unit -> IEnumerator<CacheEntry<'key,'value>>)
val values : seq<CacheEntry<'key,'value>>
module Seq

from Microsoft.FSharp.Collections
val map : mapping:('T -> 'U) -> source:seq<'T> -> seq<'U>

Full name: Microsoft.FSharp.Collections.Seq.map
val kvp : KeyValuePair<'key,CacheEntry<'key,'value>>
property KeyValuePair.Value: CacheEntry<'key,'value>
IEnumerable.GetEnumerator() : IEnumerator<CacheEntry<'key,'value>>
val entry : CacheEntry<'key,'value>
ConcurrentDictionary.AddOrUpdate(key: 'key, addValue: CacheEntry<'key,'value>, updateValueFactory: Func<'key,CacheEntry<'key,'value>,CacheEntry<'key,'value>>) : CacheEntry<'key,'value>
ConcurrentDictionary.AddOrUpdate(key: 'key, addValueFactory: Func<'key,CacheEntry<'key,'value>>, updateValueFactory: Func<'key,CacheEntry<'key,'value>,CacheEntry<'key,'value>>) : CacheEntry<'key,'value>
val ignore : value:'T -> unit

Full name: Microsoft.FSharp.Core.Operators.ignore
val __ : IMemoryCacheStore<'key,'value>
abstract member private IMemoryCacheStore.GetOrAdd : 'key -> ('key -> CacheEntry<'key,'value>) -> CacheEntry<'key,'value>
val key : 'key
val getValue : ('key -> CacheEntry<'key,'value>)
ConcurrentDictionary.GetOrAdd(key: 'key, value: CacheEntry<'key,'value>) : CacheEntry<'key,'value>
ConcurrentDictionary.GetOrAdd(key: 'key, valueFactory: Func<'key,CacheEntry<'key,'value>>) : CacheEntry<'key,'value>
abstract member private IMemoryCacheStore.Remove : 'key -> unit
ConcurrentDictionary.TryRemove(key: 'key, value: byref<CacheEntry<'key,'value>>) : bool
abstract member private IMemoryCacheStore.Contains : 'key -> bool
ConcurrentDictionary.ContainsKey(key: 'key) : bool
abstract member private IMemoryCacheStore.Update : 'key -> (CacheEntry<'key,'value> -> CacheEntry<'key,'value>) -> unit
val update : (CacheEntry<'key,'value> -> CacheEntry<'key,'value>)
ConcurrentDictionary.TryGetValue(key: 'key, value: byref<CacheEntry<'key,'value>>) : bool
abstract member private IMemoryCacheStore.TryFind : 'key -> CacheEntry<'key,'value> option
union case Option.Some: Value: 'T -> Option<'T>
union case Option.None: Option<'T>
Multiple items
namespace System.Collections

--------------------
namespace Microsoft.FSharp.Collections
type IEnumerator =
  member Current : obj
  member MoveNext : unit -> bool
  member Reset : unit -> unit

Full name: System.Collections.IEnumerator
val checkExpiration : (unit -> unit)
val filter : predicate:('T -> bool) -> source:seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Collections.Seq.filter
module CacheExpiration

from Script
val iter : action:('T -> unit) -> source:seq<'T> -> unit

Full name: Microsoft.FSharp.Collections.Seq.iter
val newCacheEntry : ('a -> 'b -> CacheEntry<'a,'b>)
val key : 'a
val value : 'b
val time : TimeSpan
val add : ('key -> 'value -> unit)
val value : 'value
abstract member private IMemoryCacheStore.Add : CacheEntry<'key,'value> -> unit
val remove : ('key -> unit)
val get : ('key -> 'value option)
module Option

from Microsoft.FSharp.Core
val bind : binder:('T -> 'U option) -> option:'T option -> 'U option

Full name: Microsoft.FSharp.Core.Option.bind
val getOrAdd : ('key -> 'value -> 'value)
val getOrAddResult : ('key -> (unit -> 'value) -> 'value)
val f : (unit -> 'value)
val getTimer : (TimeSpan -> Timer)
val expiration : TimeSpan
property TimeSpan.TotalSeconds: float
TimeSpan.FromMilliseconds(value: float) : TimeSpan
property TimeSpan.TotalMinutes: float
TimeSpan.FromSeconds(value: float) : TimeSpan
TimeSpan.FromMinutes(value: float) : TimeSpan
val interval : TimeSpan
Multiple items
type Timer =
  inherit Component
  new : unit -> Timer + 1 overload
  member AutoReset : bool with get, set
  member BeginInit : unit -> unit
  member Close : unit -> unit
  member Enabled : bool with get, set
  member EndInit : unit -> unit
  member Interval : float with get, set
  member Site : ISite with get, set
  member Start : unit -> unit
  member Stop : unit -> unit
  ...

Full name: System.Timers.Timer

--------------------
Timer() : unit
Timer(interval: float) : unit
property TimeSpan.TotalMilliseconds: float
val timer : Timer option
val observer : IDisposable option
val t : Timer
val disposable : IDisposable
event Timer.Elapsed: IEvent<ElapsedEventHandler,ElapsedEventArgs>
module Observable

from Microsoft.FSharp.Control
val subscribe : callback:('T -> unit) -> source:IObservable<'T> -> IDisposable

Full name: Microsoft.FSharp.Control.Observable.subscribe
Timer.Start() : unit
member MemoryCache.Add : key:'key -> value:'value -> unit

Full name: Script.MemoryCache`2.Add
val __ : MemoryCache<'key,'value>
member MemoryCache.Remove : key:'key -> unit

Full name: Script.MemoryCache`2.Remove
member MemoryCache.Get : key:'key -> 'value option

Full name: Script.MemoryCache`2.Get
member MemoryCache.GetOrAdd : key:'key -> value:'value -> 'value

Full name: Script.MemoryCache`2.GetOrAdd
member MemoryCache.GetOrAddResult : key:'key -> f:(unit -> 'value) -> 'value

Full name: Script.MemoryCache`2.GetOrAddResult
Multiple items
type AutoOpenAttribute =
  inherit Attribute
  new : unit -> AutoOpenAttribute
  new : path:string -> AutoOpenAttribute
  member Path : string

Full name: Microsoft.FSharp.Core.AutoOpenAttribute

--------------------
new : unit -> AutoOpenAttribute
new : path:string -> AutoOpenAttribute
module Memoization

from Script
Multiple items
type private MemoizationCache<'a,'b (requires equality)> =
  new : ?cacheExpirationPolicy:CacheExpirationPolicy -> MemoizationCache<'a,'b>
  member GetOrAdd : key:'a -> getValue:(unit -> 'b) -> 'b
  member TryGetValue : key:'a -> 'b option

Full name: Script.Memoization.MemoizationCache<_,_>

--------------------
private new : ?cacheExpirationPolicy:CacheExpirationPolicy -> MemoizationCache<'a,'b>
val cache : MemoryCache<string,'b>
Multiple items
val string : value:'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------
type string = String

Full name: Microsoft.FSharp.Core.string
val getKey : ('a -> string) (requires equality)
val key : 'a (requires equality)
val box : value:'T -> obj

Full name: Microsoft.FSharp.Core.Operators.box
val isNull : value:'T -> bool (requires 'T : null)

Full name: Microsoft.FSharp.Core.Operators.isNull
val typeof<'T> : Type

Full name: Microsoft.FSharp.Core.Operators.typeof
val sprintf : format:Printf.StringFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.sprintf
Object.GetHashCode() : int
member private MemoizationCache.TryGetValue : key:'a -> 'b option

Full name: Script.Memoization.MemoizationCache`2.TryGetValue
val keyString : string
member MemoryCache.Get : key:'key -> 'value option
val __ : MemoizationCache<'a,'b> (requires equality)
member private MemoizationCache.GetOrAdd : key:'a -> getValue:(unit -> 'b) -> 'b

Full name: Script.Memoization.MemoizationCache`2.GetOrAdd
val getValue : (unit -> 'b)
member MemoryCache.GetOrAddResult : key:'key -> f:(unit -> 'value) -> 'value
val private memoizeWithCache : f:('a -> 'b) -> cache:MemoizationCache<'a,'b> -> x:'a -> 'b (requires equality)

Full name: Script.Memoization.memoizeWithCache
val f : ('a -> 'b) (requires equality)
val cache : MemoizationCache<'a,'b> (requires equality)
val x : 'a (requires equality)
member private MemoizationCache.GetOrAdd : key:'a -> getValue:(unit -> 'b) -> 'b
val memoize : f:('a -> 'b) -> ('a -> 'b) (requires equality)

Full name: Script.Memoization.memoize


 Create a new function that remembers the results of the given function
 for each unique input parameter, returning the cached result instead
 of recomputing it each time the function is called, optimizing the execution speed
 at the cost of increased memory usage.

 Note: This optimization should only be used with referentially transparent functions
val memoizeWithExpiration : policy:CacheExpirationPolicy -> f:('a -> 'b) -> ('a -> 'b) (requires equality)

Full name: Script.Memoization.memoizeWithExpiration


 Create a new function that remembers the results of the given function
 for each unique input parameter, returning the cached result instead
 of recomputing it each time the function is called, optimizing the execution speed
 at the cost of increased memory usage. Uses a specified Cache Expiration Policy
 to limit the amount of time the results are stored, to allow memory to be free'd
 after a certain amount of time.

 Note: This optimization should only be used with referentially transparent functions
Raw view Test code New version

More information

Link:http://fssnip.net/7UT
Posted:5 years ago
Author:Aaron Eshbach
Tags: cache , memoization , thread safety