src/Cli/func/Telemetry/PersistenceChannel/SnapshottingCollection.cs (81 lines of code) (raw):
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System.Collections;
using System.Diagnostics;
namespace Azure.Functions.Cli.Telemetry.PersistenceChannel
{
internal abstract class SnapshottingCollection<TItem, TCollection> : ICollection<TItem>
where TCollection : class, ICollection<TItem>
{
#pragma warning disable SA1401 // Fields should be private
#pragma warning disable SA1306 // Field names should begin with lower-case letter
protected readonly TCollection Collection;
protected TCollection Snapshot;
#pragma warning restore SA1306 // Field names should begin with lower-case letter
#pragma warning restore SA1401 // Fields should be private
protected SnapshottingCollection(TCollection collection)
{
Debug.Assert(collection != null, "collection");
Collection = collection;
}
public int Count => GetSnapshot().Count;
public bool IsReadOnly => false;
public void Add(TItem item)
{
lock (Collection)
{
Collection.Add(item);
Snapshot = default(TCollection);
}
}
public void Clear()
{
lock (Collection)
{
Collection.Clear();
Snapshot = default(TCollection);
}
}
public bool Contains(TItem item)
{
return GetSnapshot().Contains(item);
}
public void CopyTo(TItem[] array, int arrayIndex)
{
GetSnapshot().CopyTo(array, arrayIndex);
}
public bool Remove(TItem item)
{
lock (Collection)
{
bool removed = Collection.Remove(item);
if (removed)
{
Snapshot = default(TCollection);
}
return removed;
}
}
public IEnumerator<TItem> GetEnumerator()
{
return GetSnapshot().GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
protected abstract TCollection CreateSnapshot(TCollection collection);
protected TCollection GetSnapshot()
{
TCollection localSnapshot = Snapshot;
if (localSnapshot == null)
{
lock (Collection)
{
Snapshot = CreateSnapshot(Collection);
localSnapshot = Snapshot;
}
}
return localSnapshot;
}
}
}