|
@@ -10,67 +10,64 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
|
public class ItemDataProvider<T>
|
|
public class ItemDataProvider<T>
|
|
where T : class
|
|
where T : class
|
|
{
|
|
{
|
|
- private readonly object _fileDataLock = new object();
|
|
|
|
- private List<T> _items;
|
|
|
|
private readonly IJsonSerializer _jsonSerializer;
|
|
private readonly IJsonSerializer _jsonSerializer;
|
|
- protected readonly ILogger Logger;
|
|
|
|
private readonly string _dataPath;
|
|
private readonly string _dataPath;
|
|
- protected readonly Func<T, T, bool> EqualityComparer;
|
|
|
|
|
|
+ private readonly object _fileDataLock = new object();
|
|
|
|
+ private T[] _items;
|
|
|
|
|
|
- public ItemDataProvider(IJsonSerializer jsonSerializer, ILogger logger, string dataPath, Func<T, T, bool> equalityComparer)
|
|
|
|
|
|
+ public ItemDataProvider(
|
|
|
|
+ IJsonSerializer jsonSerializer,
|
|
|
|
+ ILogger logger,
|
|
|
|
+ string dataPath,
|
|
|
|
+ Func<T, T, bool> equalityComparer)
|
|
{
|
|
{
|
|
|
|
+ _jsonSerializer = jsonSerializer;
|
|
Logger = logger;
|
|
Logger = logger;
|
|
_dataPath = dataPath;
|
|
_dataPath = dataPath;
|
|
EqualityComparer = equalityComparer;
|
|
EqualityComparer = equalityComparer;
|
|
- _jsonSerializer = jsonSerializer;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- public IReadOnlyList<T> GetAll()
|
|
|
|
- {
|
|
|
|
- lock (_fileDataLock)
|
|
|
|
- {
|
|
|
|
- if (_items == null)
|
|
|
|
- {
|
|
|
|
- if (!File.Exists(_dataPath))
|
|
|
|
- {
|
|
|
|
- return new List<T>();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- Logger.LogInformation("Loading live tv data from {0}", _dataPath);
|
|
|
|
- _items = GetItemsFromFile(_dataPath);
|
|
|
|
- }
|
|
|
|
|
|
+ protected ILogger Logger { get; }
|
|
|
|
|
|
- return _items.ToList();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ protected Func<T, T, bool> EqualityComparer { get; }
|
|
|
|
|
|
- private List<T> GetItemsFromFile(string path)
|
|
|
|
|
|
+ private void EnsureLoaded()
|
|
{
|
|
{
|
|
- try
|
|
|
|
|
|
+ if (_items != null)
|
|
{
|
|
{
|
|
- return _jsonSerializer.DeserializeFromFile<List<T>>(path);
|
|
|
|
|
|
+ return;
|
|
}
|
|
}
|
|
- catch (Exception ex)
|
|
|
|
|
|
+
|
|
|
|
+ if (File.Exists(_dataPath))
|
|
{
|
|
{
|
|
- Logger.LogError(ex, "Error deserializing {Path}", path);
|
|
|
|
|
|
+ Logger.LogInformation("Loading live tv data from {Path}", _dataPath);
|
|
|
|
+
|
|
|
|
+ try
|
|
|
|
+ {
|
|
|
|
+ _items = _jsonSerializer.DeserializeFromFile<T[]>(_dataPath);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ catch (Exception ex)
|
|
|
|
+ {
|
|
|
|
+ Logger.LogError(ex, "Error deserializing {Path}", _dataPath);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
- return new List<T>();
|
|
|
|
|
|
+ _items = Array.Empty<T>();
|
|
}
|
|
}
|
|
|
|
|
|
- private void UpdateList(List<T> newList)
|
|
|
|
|
|
+ private void SaveList()
|
|
{
|
|
{
|
|
- if (newList == null)
|
|
|
|
- {
|
|
|
|
- throw new ArgumentNullException(nameof(newList));
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
Directory.CreateDirectory(Path.GetDirectoryName(_dataPath));
|
|
Directory.CreateDirectory(Path.GetDirectoryName(_dataPath));
|
|
|
|
+ _jsonSerializer.SerializeToFile(_items, _dataPath);
|
|
|
|
+ }
|
|
|
|
|
|
|
|
+ public IReadOnlyList<T> GetAll()
|
|
|
|
+ {
|
|
lock (_fileDataLock)
|
|
lock (_fileDataLock)
|
|
{
|
|
{
|
|
- _jsonSerializer.SerializeToFile(newList, _dataPath);
|
|
|
|
- _items = newList;
|
|
|
|
|
|
+ EnsureLoaded();
|
|
|
|
+ return (T[])_items.Clone();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -81,18 +78,20 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
|
throw new ArgumentNullException(nameof(item));
|
|
throw new ArgumentNullException(nameof(item));
|
|
}
|
|
}
|
|
|
|
|
|
- var list = GetAll().ToList();
|
|
|
|
-
|
|
|
|
- var index = list.FindIndex(i => EqualityComparer(i, item));
|
|
|
|
-
|
|
|
|
- if (index == -1)
|
|
|
|
|
|
+ lock (_fileDataLock)
|
|
{
|
|
{
|
|
- throw new ArgumentException("item not found");
|
|
|
|
- }
|
|
|
|
|
|
+ EnsureLoaded();
|
|
|
|
|
|
- list[index] = item;
|
|
|
|
|
|
+ var index = Array.FindIndex(_items, i => EqualityComparer(i, item));
|
|
|
|
+ if (index == -1)
|
|
|
|
+ {
|
|
|
|
+ throw new ArgumentException("item not found");
|
|
|
|
+ }
|
|
|
|
|
|
- UpdateList(list);
|
|
|
|
|
|
+ _items[index] = item;
|
|
|
|
+
|
|
|
|
+ SaveList();
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
public virtual void Add(T item)
|
|
public virtual void Add(T item)
|
|
@@ -102,37 +101,58 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
|
throw new ArgumentNullException(nameof(item));
|
|
throw new ArgumentNullException(nameof(item));
|
|
}
|
|
}
|
|
|
|
|
|
- var list = GetAll().ToList();
|
|
|
|
-
|
|
|
|
- if (list.Any(i => EqualityComparer(i, item)))
|
|
|
|
|
|
+ lock (_fileDataLock)
|
|
{
|
|
{
|
|
- throw new ArgumentException("item already exists");
|
|
|
|
- }
|
|
|
|
|
|
+ EnsureLoaded();
|
|
|
|
|
|
- list.Add(item);
|
|
|
|
|
|
+ if (_items.Any(i => EqualityComparer(i, item)))
|
|
|
|
+ {
|
|
|
|
+ throw new ArgumentException("item already exists", nameof(item));
|
|
|
|
+ }
|
|
|
|
|
|
- UpdateList(list);
|
|
|
|
|
|
+ int oldLen = _items.Length;
|
|
|
|
+ var newList = new T[oldLen + 1];
|
|
|
|
+ _items.CopyTo(newList, 0);
|
|
|
|
+ newList[oldLen] = item;
|
|
|
|
+ _items = newList;
|
|
|
|
+
|
|
|
|
+ SaveList();
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
- public void AddOrUpdate(T item)
|
|
|
|
|
|
+ public virtual void AddOrUpdate(T item)
|
|
{
|
|
{
|
|
- var list = GetAll().ToList();
|
|
|
|
-
|
|
|
|
- if (!list.Any(i => EqualityComparer(i, item)))
|
|
|
|
- {
|
|
|
|
- Add(item);
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
|
|
+ lock (_fileDataLock)
|
|
{
|
|
{
|
|
- Update(item);
|
|
|
|
|
|
+ EnsureLoaded();
|
|
|
|
+
|
|
|
|
+ int index = Array.FindIndex(_items, i => EqualityComparer(i, item));
|
|
|
|
+ if (index == -1)
|
|
|
|
+ {
|
|
|
|
+ int oldLen = _items.Length;
|
|
|
|
+ var newList = new T[oldLen + 1];
|
|
|
|
+ _items.CopyTo(newList, 0);
|
|
|
|
+ newList[oldLen] = item;
|
|
|
|
+ _items = newList;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ _items[index] = item;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ SaveList();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
public virtual void Delete(T item)
|
|
public virtual void Delete(T item)
|
|
{
|
|
{
|
|
- var list = GetAll().Where(i => !EqualityComparer(i, item)).ToList();
|
|
|
|
|
|
+ lock (_fileDataLock)
|
|
|
|
+ {
|
|
|
|
+ EnsureLoaded();
|
|
|
|
+ _items = _items.Where(i => !EqualityComparer(i, item)).ToArray();
|
|
|
|
|
|
- UpdateList(list);
|
|
|
|
|
|
+ SaveList();
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|