Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

New UberMemoizer class makes it super simple to memoize many function…

…s without having to keep multiple memoizers around.
  • Loading branch information...
commit 9c42c3d61e83a3b2c20d3c0579b2a8165f143845 1 parent ab6543d
@rmoritz authored
View
2  .gitignore
@@ -1,4 +1,4 @@
-**~
+*~
*.suo
bin
obj
View
4 Examples/Factory/Examples.Factory.csproj → Examples/Uber/Examples.Uber.csproj
@@ -7,8 +7,8 @@
<ProjectGuid>{592FD4FE-AB9B-4C91-B712-5278E8869993}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>Examples.Factory</RootNamespace>
- <AssemblyName>Examples.Factory</AssemblyName>
+ <RootNamespace>Examples.Uber</RootNamespace>
+ <AssemblyName>Examples.Uber</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
View
15 Examples/Factory/Program.cs → Examples/Uber/Program.cs
@@ -6,7 +6,7 @@
using System.Threading.Tasks;
using Recall;
-namespace Examples.Factory
+namespace Examples.Uber
{
internal class Program
{
@@ -42,18 +42,7 @@ private static void Main()
{
Console.WriteLine("Executing queries. Please be patient.");
- var factory = new MemoizerFactory
- {
- GenericCacheType = typeof(Dictionary<,>),
- Settings = new MemoizerSettings
- {
- MaxAge = TimeSpan.FromSeconds(5),
- MaxItems = 10000
- }
- };
-
- var memoizer = factory.Create<int>();
- var memoizedTaskAsyncFunc = memoizer.MemoizeTask<int>(TaskAsyncQuery);
+ var memoizedTaskAsyncFunc = UberMemoizer.DefaultInstance.MemoizeTask<int, int>(TaskAsyncQuery);
ExecuteTaskAsyncQuery(memoizedTaskAsyncFunc, QueryArg).Wait();
ExecuteTaskAsyncQuery(memoizedTaskAsyncFunc, QueryArg).Wait();
View
10 Examples/Factory/Properties/AssemblyInfo.cs → Examples/Uber/Properties/AssemblyInfo.cs
@@ -5,12 +5,12 @@
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
-[assembly: AssemblyTitle("Examples.Factory")]
-[assembly: AssemblyDescription("")]
+[assembly: AssemblyTitle("Examples.Uber")]
+[assembly: AssemblyDescription("Part of Recall, a memoization library for .NET")]
[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("Examples.Factory")]
-[assembly: AssemblyCopyright("Copyright © 2013")]
+[assembly: AssemblyCompany("Ralph Möritz")]
+[assembly: AssemblyProduct("Recall")]
+[assembly: AssemblyCopyright("Copyright © Ralph Möritz 2012")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
View
3  README.md
@@ -16,8 +16,7 @@ static void Main()
{
Console.WriteLine("Executing queries. Please be patient.");
- var memoizer = new Memoizer<int, Dictionary<string, CacheEntry<int>>>();
- var memoizedTaskAsyncFunc = memoizer.MemoizeTask<int>(TaskAsyncQuery);
+ var memoizedTaskAsyncFunc = UberMemoizer.DefaultInstance.MemoizeTask<int, int>(TaskAsyncQuery);
ExecuteTaskAsyncQuery(memoizedTaskAsyncFunc, QueryArg).Wait();
ExecuteTaskAsyncQuery(memoizedTaskAsyncFunc, QueryArg).Wait();
View
2  Recall.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>Recall</id>
- <version>1.0.2</version>
+ <version>1.0.3</version>
<authors>Ralph Möritz</authors>
<owners>Ralph Möritz</owners>
<projectUrl>https://github.com/ralph-moeritz/Recall</projectUrl>
View
2  Recall.sln
@@ -29,7 +29,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{93DB80
.nuget\NuGet.targets = .nuget\NuGet.targets
EndProjectSection
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Examples.Factory", "Examples\Factory\Examples.Factory.csproj", "{592FD4FE-AB9B-4C91-B712-5278E8869993}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Examples.Uber", "Examples\Uber\Examples.Uber.csproj", "{592FD4FE-AB9B-4C91-B712-5278E8869993}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
View
50 Recall/Defaults.cs
@@ -0,0 +1,50 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Recall
+{
+ internal class Defaults
+ {
+ public static Type DefaultGenericCacheType
+ {
+ get { return typeof(Dictionary<,>); }
+ }
+
+ public static MemoizerSettings DefaultMemoizerSettings
+ {
+ get
+ {
+ return new MemoizerSettings
+ {
+ MaxAge = TimeSpan.FromMinutes(5),
+ MaxItems = 10000
+ };
+ }
+ }
+
+ public static IMemoizerFactory DefaultMemoizerFactory
+ {
+ get
+ {
+ return new MemoizerFactory
+ {
+ GenericCacheType = DefaultGenericCacheType,
+ Settings = DefaultMemoizerSettings
+ };
+ }
+ }
+
+ public static IUberMemoizer DefaultUberMemoizer
+ {
+ get
+ {
+ return new UberMemoizer
+ {
+ Factory = DefaultMemoizerFactory
+ };
+ }
+ }
+ }
+}
View
15 Recall/IMemoizer.cs
@@ -5,6 +5,21 @@
namespace Recall
{
+ public interface IMemoizer
+ {
+ MemoizedFunc<TResult> Memoize<TResult>(Func<IEnumerable<TResult>> func);
+
+ MemoizedFunc<TArg, TResult> Memoize<TArg, TResult>(Func<TArg, IEnumerable<TResult>> func);
+
+ MemoizedAsyncFunc<TResult> Memoize<TResult>(Action<Action<IEnumerable<TResult>>> action);
+
+ MemoizedAsyncFunc<TArg, TResult> Memoize<TArg, TResult>(Action<TArg, Action<IEnumerable<TResult>>> action);
+
+ MemoizedTaskAsyncFunc<TResult> MemoizeTask<TResult>(Func<Task<IEnumerable<TResult>>> func);
+
+ MemoizedTaskAsyncFunc<TArg, TResult> MemoizeTask<TArg, TResult>(Func<TArg, Task<IEnumerable<TResult>>> func);
+ }
+
public interface IMemoizer<TResult>
{
MemoizerSettings Settings { get; set; }
View
12 Recall/IUberMemoizer.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Recall
+{
+ public interface IUberMemoizer : IMemoizer
+ {
+ IMemoizerFactory Factory { get; set; }
+ }
+}
View
39 Recall/Memoizer.cs
@@ -13,12 +13,6 @@ public sealed class Memoizer<TResult, TCache> : IMemoizer<TResult>
public static readonly Func<IEnumerable<KeyValuePair<string, CacheEntry<TResult>>>,
IOrderedEnumerable<KeyValuePair<string, CacheEntry<TResult>>>> DefaultEvictionOrderer = EvictionPolicy.LRU;
- private static readonly MemoizerSettings DefaultSettings = new MemoizerSettings
- {
- MaxAge = TimeSpan.FromMinutes(5),
- MaxItems = 10000
- };
- private static Memoizer<TResult, TCache> _defaultInstance;
#endregion
@@ -26,15 +20,24 @@ public sealed class Memoizer<TResult, TCache> : IMemoizer<TResult>
private readonly TCache _cache = new TCache();
private readonly object _locker = new object();
+ private MemoizerSettings _settings = Defaults.DefaultMemoizerSettings;
+
+ public Func<IEnumerable<KeyValuePair<string, CacheEntry<TResult>>>,
+ IOrderedEnumerable<KeyValuePair<string, CacheEntry<TResult>>>> EvictionOrderer { get; set; }
#endregion
- #region Implementation of IMemoizer
+ #region Properties
+
+ public MemoizerSettings Settings
+ {
+ get { return _settings; }
+ set { _settings = value; }
+ }
- public MemoizerSettings Settings { get; set; }
+ #endregion
- public Func<IEnumerable<KeyValuePair<string, CacheEntry<TResult>>>,
- IOrderedEnumerable<KeyValuePair<string, CacheEntry<TResult>>>> EvictionOrderer { get; set; }
+ #region Public Methods
public MemoizedFunc<TResult> Memoize(Func<IEnumerable<TResult>> func)
{
@@ -343,21 +346,7 @@ public MemoizedTaskAsyncFunc<TResult> MemoizeTask(Func<Task<IEnumerable<TResult>
#endregion
- #region Utility Functions
-
- public static Memoizer<TResult, TCache> DefaultInstance
- {
- get { return _defaultInstance ?? CreateDefaultInstance(); }
- }
-
- private static Memoizer<TResult, TCache> CreateDefaultInstance()
- {
- _defaultInstance = new Memoizer<TResult, TCache>
- {
- Settings = DefaultSettings
- };
- return _defaultInstance;
- }
+ #region Private Methods
private void Invalidate(string key)
{
View
39 Recall/MemoizerFactory.cs
@@ -4,21 +4,46 @@ namespace Recall
{
public sealed class MemoizerFactory : IMemoizerFactory
{
+ #region Static Fields
+
+ public static IMemoizerFactory DefaultInstance = Defaults.DefaultMemoizerFactory;
+
private static readonly Type GenericMemoizerType = typeof(Memoizer<,>);
- #region Implementation of IMemoizerFactory
+ #endregion
+
+ #region Fields
+
+ private MemoizerSettings _settings = Defaults.DefaultMemoizerSettings;
+ private Type _genericCacheType = Defaults.DefaultGenericCacheType;
+
+ #endregion
+
+ #region Properties
- public MemoizerSettings Settings { get; set; }
+ public MemoizerSettings Settings
+ {
+ get { return _settings; }
+ set { _settings = value; }
+ }
+
+ public Type GenericCacheType
+ {
+ get { return _genericCacheType; }
+ set { _genericCacheType = value; }
+ }
+
+ #endregion
- public Type GenericCacheType { get; set; }
+ #region Public Methods
- public IMemoizer<T> Create<T>()
+ public IMemoizer<TResult> Create<TResult>()
{
- var constructedCacheType = GenericCacheType.MakeGenericType(typeof(string), typeof (CacheEntry<T>));
- var constructedMemoizerType = GenericMemoizerType.MakeGenericType(typeof (T), constructedCacheType);
+ var constructedCacheType = GenericCacheType.MakeGenericType(typeof(string), typeof (CacheEntry<TResult>));
+ var constructedMemoizerType = GenericMemoizerType.MakeGenericType(typeof (TResult), constructedCacheType);
var ctor = constructedMemoizerType.GetConstructor(new Type[]{});
- var memoizer = (IMemoizer<T>)ctor.Invoke(null);
+ var memoizer = (IMemoizer<TResult>) ctor.Invoke(null);
memoizer.Settings = Settings;
return memoizer;
}
View
3  Recall/Recall.csproj
@@ -38,14 +38,17 @@
</ItemGroup>
<ItemGroup>
<Compile Include="CacheEntry.cs" />
+ <Compile Include="Defaults.cs" />
<Compile Include="EvictionPolicy.cs" />
<Compile Include="IMemoizer.cs" />
<Compile Include="IMemoizerFactory.cs" />
+ <Compile Include="IUberMemoizer.cs" />
<Compile Include="MemoizedFunc.cs" />
<Compile Include="Memoizer.cs" />
<Compile Include="MemoizerFactory.cs" />
<Compile Include="MemoizerSettings.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="UberMemoizer.cs" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
<PropertyGroup>
View
90 Recall/UberMemoizer.cs
@@ -0,0 +1,90 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Recall
+{
+ public sealed class UberMemoizer : IUberMemoizer
+ {
+ #region Static Fields
+
+ public static readonly IUberMemoizer DefaultInstance = Defaults.DefaultUberMemoizer;
+
+ #endregion
+
+ #region Fields
+
+ private IDictionary<Type, object> _memoizers = new Dictionary<Type, object>();
+ private IMemoizerFactory _factory = Defaults.DefaultMemoizerFactory;
+
+ #endregion
+
+ #region Properties
+
+ public IMemoizerFactory Factory
+ {
+ get { return _factory; }
+ set { _factory = value; }
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ public MemoizedFunc<TResult> Memoize<TResult>(Func<IEnumerable<TResult>> func)
+ {
+ var memoizer = GetMemoizer<TResult>();
+ return memoizer.Memoize(func);
+ }
+
+ public MemoizedFunc<TArg, TResult> Memoize<TArg, TResult>(Func<TArg, IEnumerable<TResult>> func)
+ {
+ var memoizer = GetMemoizer<TResult>();
+ return memoizer.Memoize<TArg>(func);
+ }
+
+ public MemoizedAsyncFunc<TResult> Memoize<TResult>(Action<Action<IEnumerable<TResult>>> action)
+ {
+ var memoizer = GetMemoizer<TResult>();
+ return memoizer.Memoize(action);
+ }
+
+ public MemoizedAsyncFunc<TArg, TResult> Memoize<TArg, TResult>(Action<TArg, Action<IEnumerable<TResult>>> action)
+ {
+ var memoizer = GetMemoizer<TResult>();
+ return memoizer.Memoize<TArg>(action);
+ }
+
+ public MemoizedTaskAsyncFunc<TResult> MemoizeTask<TResult>(Func<Task<IEnumerable<TResult>>> func)
+ {
+ var memoizer = GetMemoizer<TResult>();
+ return memoizer.MemoizeTask(func);
+ }
+
+ public MemoizedTaskAsyncFunc<TArg, TResult> MemoizeTask<TArg, TResult>(Func<TArg, Task<IEnumerable<TResult>>> func)
+ {
+ var memoizer = GetMemoizer<TResult>();
+ return memoizer.MemoizeTask<TArg>(func);
+ }
+
+ #endregion
+
+ #region Private Methods
+
+ private IMemoizer<TResult> GetMemoizer<TResult>()
+ {
+ var t = typeof (TResult);
+ object memoizer;
+ if (!_memoizers.TryGetValue(t, out memoizer))
+ {
+ memoizer = Factory.Create<TResult>();
+ _memoizers.Add(t, memoizer);
+ }
+ return (IMemoizer<TResult>) memoizer;
+ }
+
+ #endregion
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.