using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using ServiceStack.Common;
namespace ServiceStack.ServiceInterface.Auth
{
///
/// Thread-safe In memory UserAuth data store so it can be used without a dependency on Redis.
///
public class InMemoryAuthRepository : RedisAuthRepository
{
public static readonly InMemoryAuthRepository Instance = new InMemoryAuthRepository();
protected Dictionary> Sets { get; set; }
protected Dictionary> Hashes { get; set; }
internal List TrackedTypes = new List();
class TypedData : IClearable
{
internal static TypedData Instance = new TypedData();
private TypedData()
{
lock (InMemoryAuthRepository.Instance.TrackedTypes)
InMemoryAuthRepository.Instance.TrackedTypes.Add(this);
}
internal readonly List Items = new List();
internal int Sequence = 0;
public void Clear()
{
lock (Items) Items.Clear();
Interlocked.CompareExchange(ref Sequence, 0, Sequence);
}
}
public InMemoryAuthRepository() : base(new InMemoryManagerFacade(Instance))
{
this.Sets = new Dictionary>();
this.Hashes = new Dictionary>();
}
class InMemoryManagerFacade : IRedisClientManagerFacade
{
private readonly InMemoryAuthRepository root;
public InMemoryManagerFacade(InMemoryAuthRepository root)
{
this.root = root;
}
public IRedisClientFacade GetClient()
{
return new InMemoryClientFacade(root);
}
public void Clear()
{
lock (Instance.Sets) Instance.Sets.Clear();
lock (Instance.Hashes) Instance.Hashes.Clear();
lock (Instance.TrackedTypes) Instance.TrackedTypes.ForEach(x => x.Clear());
}
}
class InMemoryClientFacade : IRedisClientFacade
{
private readonly InMemoryAuthRepository root;
public InMemoryClientFacade(InMemoryAuthRepository root)
{
this.root = root;
}
class InMemoryTypedClientFacade : ITypedRedisClientFacade
{
private readonly InMemoryAuthRepository root;
public InMemoryTypedClientFacade(InMemoryAuthRepository root)
{
this.root = root;
}
public int GetNextSequence()
{
return Interlocked.Increment(ref TypedData.Instance.Sequence);
}
public T GetById(object id)
{
if (id == null) return default(T);
lock (TypedData.Instance.Items)
{
return TypedData.Instance.Items.FirstOrDefault(x => id.ToString() == x.ToId().ToString());
}
}
public List GetByIds(IEnumerable ids)
{
var idsSet = new HashSet