6 people like it.

Concurrent Memoization

This is more generic variant of http://www.fssnip.net/c4 if you want to memoize over different functions / code paths that calls the same to-be-cached-code.

1: 
2: 
3: 
4: 
5: 
6: 
7: 
8: 
module Memoize

//More generic variant of http://www.fssnip.net/c4  
open System.Collections.Concurrent  
let cache = ConcurrentDictionary<(string * obj),Lazy<obj>>()  
let memoizeConcurrent (caller:string) (f: ('a -> 'b)) =  
    fun (x :'a) ->   
        (cache.GetOrAdd((caller, x|>box), lazy ((f x)|>box)).Force() |> unbox) : 'b  
module Memoize
namespace System
namespace System.Collections
namespace System.Collections.Concurrent
val cache : ConcurrentDictionary<(string * obj),Lazy<obj>>

Full name: Memoize.cache
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: System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<'TKey,'TValue>>) : unit
ConcurrentDictionary(comparer: System.Collections.Generic.IEqualityComparer<'TKey>) : unit
ConcurrentDictionary(concurrencyLevel: int, capacity: int) : unit
ConcurrentDictionary(collection: System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<'TKey,'TValue>>, comparer: System.Collections.Generic.IEqualityComparer<'TKey>) : unit
ConcurrentDictionary(concurrencyLevel: int, collection: System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<'TKey,'TValue>>, comparer: System.Collections.Generic.IEqualityComparer<'TKey>) : unit
ConcurrentDictionary(concurrencyLevel: int, capacity: int, comparer: System.Collections.Generic.IEqualityComparer<'TKey>) : unit
Multiple items
val string : value:'T -> string

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

--------------------
type string = System.String

Full name: Microsoft.FSharp.Core.string
type obj = System.Object

Full name: Microsoft.FSharp.Core.obj
Multiple items
active recognizer Lazy: Lazy<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.( |Lazy| )

--------------------
type Lazy<'T> = System.Lazy<'T>

Full name: Microsoft.FSharp.Control.Lazy<_>
val memoizeConcurrent : caller:string -> f:('a -> 'b) -> x:'a -> 'b

Full name: Memoize.memoizeConcurrent
val caller : string
val f : ('a -> 'b)
val x : 'a
ConcurrentDictionary.GetOrAdd(key: string * obj, value: Lazy<obj>) : Lazy<obj>
ConcurrentDictionary.GetOrAdd(key: string * obj, valueFactory: System.Func<(string * obj),Lazy<obj>>) : Lazy<obj>
val box : value:'T -> obj

Full name: Microsoft.FSharp.Core.Operators.box
val unbox : value:obj -> 'T

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

More information

Link:http://fssnip.net/sA
Posted:8 years ago
Author:Tuomas Hietanen
Tags: memoize , memoization , cache