Skip to content

Commit

Permalink
Missing source file
Browse files Browse the repository at this point in the history
  • Loading branch information
jaquadro committed Nov 1, 2013
1 parent 346adf2 commit ae03136
Showing 1 changed file with 210 additions and 0 deletions.
210 changes: 210 additions & 0 deletions SnapshotList.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;

namespace NBTExplorer
{
public class SnapshotState<T> : IDisposable
{
private SnapshotList<T> _list;

internal SnapshotState (SnapshotList<T> list)
{
_list = list;
_list.Begin();
}

public void Dispose ()
{
_list.End();
GC.SuppressFinalize(this);
}
}

public class SnapshotList<T> : Collection<T>
{
private IList<T> _snapshot;
private IList<T> _recycled;
private int _snapshots;

public SnapshotList ()
: base(new ProxyList<T>())
{ }

public SnapshotList (IList<T> list)
: base(new ProxyList<T>(new List<T>(list)))
{ }

public SnapshotList (int capacity)
: base(new ProxyList<T>(new List<T>(capacity)))
{ }

private new ProxyList<T> Items
{
get { return base.Items as ProxyList<T>; }
}

public IList<T> Begin ()
{
Modified();
_snapshot = Items.InnerList;
_snapshots++;
return _snapshot;
}

public void End ()
{
_snapshots = Math.Max(0, _snapshots - 1);
if (_snapshot == null)
return;

// The backing array was copied, keep around the old array
if (_snapshot != Items.InnerList && _snapshots == 0) {
_recycled = _snapshot;
_recycled.Clear();
//for (int i = 0, n = _recycled.Count; i < n; i++)
// _recycled[i] = default(T);
}

_snapshot = null;
}

public SnapshotState<T> Snapshot ()
{
return new SnapshotState<T>(this);
}

private void Modified ()
{
if (_snapshot == null || _snapshot != Items.InnerList)
return;

// Snapshot is in use, copy backing array to recycled array or create new backing array
if (_recycled != null) {
for (int i = 0; i < Count; i++)
_recycled.Add(Items[i]);
Items.InnerList = _recycled;
_recycled = null;
}
else
Resize(Items.Count);
}

private void Resize (int newSize)
{
IList<T> oldList = Items.InnerList;
List<T> newList = new List<T>(newSize);
for (int i = 0, n = oldList.Count; i < n; i++)
newList.Add(oldList[i]);

Items.InnerList = newList;
}

protected override void InsertItem (int index, T item)
{
Modified();
base.InsertItem(index, item);
}

protected override void SetItem (int index, T item)
{
Modified();
base.SetItem(index, item);
}

protected override void RemoveItem (int index)
{
Modified();
base.RemoveItem(index);
}

protected override void ClearItems ()
{
Modified();
base.ClearItems();
}

private class ProxyList<K> : IList<K>
{
public IList<K> InnerList { get; set; }

public ProxyList ()
{
InnerList = new List<K>();
}

public ProxyList (IList<K> list)
{
InnerList = list;
}

public int IndexOf (K item)
{
return InnerList.IndexOf(item);
}

public void Insert (int index, K item)
{
InnerList.Insert(index, item);
}

public void RemoveAt (int index)
{
InnerList.RemoveAt(index);
}

public K this[int index]
{
get { return InnerList[index]; }
set { InnerList[index] = value; }
}

public void Add (K item)
{
InnerList.Add(item);
}

public void Clear ()
{
InnerList.Clear();
}

public bool Contains (K item)
{
return InnerList.Contains(item);
}

public void CopyTo (K[] array, int arrayIndex)
{
InnerList.CopyTo(array, arrayIndex);
}

public int Count
{
get { return InnerList.Count; }
}

public bool IsReadOnly
{
get { return InnerList.IsReadOnly; }
}

public bool Remove (K item)
{
return InnerList.Remove(item);
}

public IEnumerator<K> GetEnumerator ()
{
return InnerList.GetEnumerator();
}

IEnumerator IEnumerable.GetEnumerator ()
{
return InnerList.GetEnumerator();
}
}
}
}

0 comments on commit ae03136

Please sign in to comment.