using System; using System.Collections; using System.Collections.Generic; using System.Linq; using HeuristicLab.Data.PersistentDataStructures.Implementations; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; namespace HeuristicLab.Data.PersistentDataStructures.Adaptations { [StorableClass] public class HistoryList : IList { [Storable] private readonly ArrayMappedTrie amt; public int Count { get; private set; } [StorableConstructor] protected HistoryList(bool isDesierializing) { } public HistoryList() { amt = new ArrayMappedTrie(true); Count = 0; } public T this[int index] { get { if (index < 0 || index >= Count) throw new IndexOutOfRangeException(); return amt[(UInt32) index]; } set { if (index < 0 || index >= Count) throw new IndexOutOfRangeException(); amt[(UInt32) index] = value; } } public IEnumerator GetEnumerator() { for (int i = 0; i < Count; i++) yield return amt[(UInt32)i]; } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public void Add(T item) { amt[(UInt32)Count] = item; Count++; } public void Clear() { amt.Clear(); } public bool Contains(T item) { return amt.Contains(item); } public void CopyTo(T[] array, int arrayIndex) { for (int i = 0; i < Count && i < array.Length + arrayIndex; i++) { array[i + arrayIndex] = this[i]; } } public bool Remove(T item) { var oldInternval = amt.SnapshotInterval; amt.SnapshotInterval = 0; bool found = false; var wi = 0; for (int i = 0; i < Count; i++) { var value = amt[(UInt32) i]; if (!value.Equals(item)) { if (wi < i) amt[(UInt32) wi] = value; wi++; } } found = wi < Count; while (wi < Count) { amt.Remove((UInt32) wi); wi++; Count--; } amt.SnapshotInterval = oldInternval; if (oldInternval > 0) amt.CreateSnapshot(); return found; } public bool IsReadOnly { get { return false; } } public int IndexOf(T item) { for (int i = 0; i < Count; i++) { if (amt[(UInt32)i].Equals(item)) return i; } return -1; } public void Insert(int index, T item) { var oldInterval = amt.SnapshotInterval; amt.SnapshotInterval = 0; for (int i = Count; i > index; i--) { amt[(UInt32)i] = amt[(UInt32)i - 1]; } amt[(UInt32) index] = item; Count++; amt.SnapshotInterval = oldInterval; if (oldInterval > 0) amt.CreateSnapshot(); } public void RemoveAt(int index) { var oldInterval = amt.SnapshotInterval; amt.SnapshotInterval = 0; for (int i = index; i < Count; i++) { amt[(UInt32)i] = amt[(UInt32)i + 1]; } amt.Remove((UInt32)Count-1); amt.SnapshotInterval = oldInterval; if (oldInterval > 0) amt.CreateSnapshot(); } } }