// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
namespace Microsoft.Teams.Common.Storage;
///
/// a local in-memory `IStorage` implementation
///
/// the value type
public class LocalStorage : IStorage
{
protected Dictionary _store = [];
protected IList _keys = [];
protected int? _max;
///
/// the number of items in the storage
///
public int Size => _store.Count;
///
/// get the list of storage keys
///
public IList Keys => _store.Keys.ToList();
public LocalStorage(int? max = null)
{
_max = max;
}
public LocalStorage(IDictionary data, int? max)
{
_store = new Dictionary(data);
_keys = data.Keys.ToList();
_max = max;
}
public bool Exists(string key) => _store.ContainsKey(key);
public Task ExistsAsync(string key) => Task.FromResult(Exists(key));
public TValue? Get(string key)
{
Hit(key);
return _store.TryGetValue(key, out var value) ? value : default;
}
public T? Get(string key) where T : TValue
{
var value = Get(key);
return (T?)value;
}
public Task GetAsync(string key)
{
return Task.FromResult(Get(key));
}
public async Task GetAsync(string key) where T : TValue
{
var value = await GetAsync(key).ConfigureAwait(false);
return (T?)value;
}
public void Set(string key, TValue value)
{
if (!Hit(key)) _keys.Add(key);
if (_max is not null)
{
if (_keys.Count > _max)
{
var toRemove = _keys.ElementAt(0);
_keys.RemoveAt(0);
_store.Remove(toRemove);
}
}
_store[key] = value;
}
public Task SetAsync(string key, TValue value)
{
Set(key, value);
return Task.CompletedTask;
}
public void Delete(string key)
{
var index = _keys.IndexOf(key);
if (index == -1) return;
_keys.RemoveAt(index);
_store.Remove(key);
}
public Task DeleteAsync(string key)
{
Delete(key);
return Task.CompletedTask;
}
protected bool Hit(string key)
{
if (!Exists(key)) return false;
if (Keys.Last() == key) return true;
var index = _keys.IndexOf(key);
if (index < 0) return false;
for (var i = index + 1; i < _keys.Count; i++)
{
var tmp = _keys[i - 1];
_keys[i - 1] = _keys[i];
_keys[i] = tmp;
}
return true;
}
}