Created
August 24, 2011 11:15
-
-
Save ThatRendle/1167813 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace ElegantCache | |
{ | |
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Linq; | |
using System.Net; | |
using System.Runtime.Caching; | |
class ElegantCache<TValue> : IDisposable | |
{ | |
private readonly MemoryCache _cache = new MemoryCache(Guid.NewGuid().ToString()); | |
private readonly CacheItemPolicy _cacheItemPolicy; | |
private readonly Func<TValue, string> _keyResolver; | |
private readonly Func<IEnumerable<string>, IEnumerable<TValue>> _uncachedResolver; | |
public ElegantCache(CacheItemPolicy cacheItemPolicy, | |
Func<TValue, string> keyResolver, | |
Func<IEnumerable<string>, IEnumerable<TValue>> uncachedResolver) | |
{ | |
_cacheItemPolicy = cacheItemPolicy; | |
_keyResolver = keyResolver; | |
_uncachedResolver = uncachedResolver; | |
} | |
public IEnumerable<TValue> Get(string[] keys) | |
{ | |
var values = _cache.GetValues(keys) ?? new Dictionary<string, object>(); | |
if (values.Count(kvp => kvp.Value != null) < keys.Length) | |
{ | |
GetUncachedValues(keys, values); | |
} | |
return keys.Select(key => values[key]).Cast<TValue>(); | |
} | |
private void GetUncachedValues(string[] keys, IDictionary<string, object> values) | |
{ | |
foreach (var value in _uncachedResolver(keys.Where(k => values[k] == null))) | |
{ | |
var key = _keyResolver(value); | |
values[key] = value; | |
_cache.Set(key, value, _cacheItemPolicy); | |
} | |
} | |
public void Dispose() | |
{ | |
_cache.Dispose(); | |
} | |
} | |
public class ClientProxy : IDisposable | |
{ | |
readonly ElegantCache<JsonDocument> _cache = | |
new ElegantCache<JsonDocument>(new CacheItemPolicy(), json => json.ID, GetDocumentsFromServer); | |
public JsonDocument[] GetDocument(params string[] ids) | |
{ | |
return _cache.Get(ids).ToArray(); | |
} | |
private static IEnumerable<JsonDocument> GetDocumentsFromServer(IEnumerable<string> ids) | |
{ | |
var request = WebRequest.Create("http://server/get?id=" + string.Join("&id=", ids)); | |
using (var stream = request.GetResponse().GetResponseStream()) | |
{ | |
return GetResults(stream); | |
} | |
} | |
private static JsonDocument[] GetResults(Stream stream) | |
{ | |
// Parse stream | |
} | |
public void Dispose() | |
{ | |
_cache.Dispose(); | |
} | |
} | |
public class JsonDocument | |
{ | |
public string ID { get; set; } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The eventual, non-memory-leaking, thread-safe, performant and still, I think, elegant solution to Ayende's challenge here: http://ayende.com/blog/60417/elegancy-challenge-cacheable-batches