using System;
using System.Collections.Concurrent;
using System.Threading.Tasks;
namespace Wabbajack.Common;
///
/// Represents a cache where values are created on-the-fly when they are found missing.
/// Creating a value locks the cache entry so that each key/value pair is only created once.
///
///
///
public class LazyCache
where TKey : notnull
{
private readonly ConcurrentDictionary> _data;
private readonly Func _selector;
private readonly Func> _valueFactory;
public LazyCache(Func selector, Func> valueFactory)
{
_selector = selector;
_valueFactory = valueFactory;
_data = new ConcurrentDictionary>();
}
public async ValueTask Get(TArg lookup)
{
var key = _selector(lookup);
while (true)
{
if (_data.TryGetValue(key, out var found))
return await found.Value;
var value = new AsyncLazy(() => _valueFactory(lookup));
if (_data.TryAdd(key, value))
return await value.Value;
}
}
}