source: branches/PersistentDataStructures/HeuristicLab.Data/3.3/PersistentDataStructures/Adaptations/HistoryArray.cs @ 14657

Last change on this file since 14657 was 14657, checked in by epitzer, 4 years ago

#2727 add generic MetaInfo to AMT e.g. for tracking Count in facades

File size: 4.8 KB
Line 
1using System;
2using System.Collections;
3using System.Collections.Generic;
4using System.Linq;
5using HeuristicLab.Data.PersistentDataStructures.Implementations;
6using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
7
8namespace HeuristicLab.Data.PersistentDataStructures.Adaptations {
9
10  [StorableClass]
11  public class HistoryArray<T> : ICloneable, IList<T>, ICollection, IEnumerable, IStructuralComparable, IStructuralEquatable {
12
13    [Storable]
14    private ArrayMappedTrie<T> amt;
15
16    public int Count {
17      get { return (int?) amt.MetaInfo ?? 0; }
18      private set { amt.MetaInfo = value; }
19    }
20
21    public int Length { get { return Count; } }
22
23    [StorableConstructor]
24    protected HistoryArray(bool isDeserializing) { }
25
26    private HistoryArray(ArrayMappedTrie<T> amt) {
27      this.amt = amt.Clone();
28      Count = (int?) amt.MetaInfo ?? 0;
29    }
30
31    protected HistoryArray(HistoryArray<T> orig) {
32      amt = orig.amt.Clone();
33      Count = orig.Count;
34    }
35
36    public HistoryArray(int size) {
37      amt = new ArrayMappedTrie<T> { SnapshotInterval = 0 };
38      Count = size;
39    }
40
41    [Obsolete]
42    public HistoryArray(IEnumerable<T> elements) {
43      amt = new ArrayMappedTrie<T> { SnapshotInterval = 0 };
44      Count = 0;
45      foreach (var element in elements) {
46        Add(element);
47      }
48    }
49
50    public T this[int index] {
51      get {
52        if (index < 0 || index >= Count) throw new IndexOutOfRangeException();
53        return amt[(UInt32) index];
54      }
55      set {
56        if (index < 0 || index >= Count) throw new IndexOutOfRangeException();
57        amt[(UInt32) index] = value;
58      }
59    }
60
61    IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
62
63    public IEnumerator<T> GetEnumerator() {
64      for (int i = 0; i < Count; i++) {
65        yield return this[i];
66      }
67    }
68
69    public object Clone() { return new HistoryArray<T>(this); }
70    public void Add(T item) { amt[(UInt32)Count] = item; Count++; }
71
72    public void Clear() {
73      var oldInterval = amt.SnapshotInterval;
74      amt.SnapshotInterval = 0;
75      for (int i = 0; i < Count; i++)
76        this[i] = default(T);
77      amt.SnapshotInterval = oldInterval;
78      if (oldInterval > 0)
79        amt.CreateSnapshot();
80    }
81    public bool Contains(T item) { return amt.Any(i => i.Equals(item)); }
82
83    public void CopyTo(T[] array, int arrayIndex) {
84      for (int i = 0; i < Count && i+arrayIndex < array.Length; i++) {
85        array[i + arrayIndex] = this[i];
86      }
87    }
88
89    public bool Remove(T item) { throw new NotSupportedException(); }
90    int ICollection<T>.Count { get { return Count;  } }
91
92    public bool IsReadOnly { get { return false;  } }
93    public int IndexOf(T item) {
94      for (int i = 0; i < Count; i++) {
95        if (this[i].Equals(item)) return i;
96      }
97      return -1;
98    }
99    public void Insert(int index, T item) { throw new NotSupportedException(); }
100    public void RemoveAt(int index) { throw new NotSupportedException(); }
101
102    public void CopyTo(Array array, int index) {
103      for (int i = 0; i < Count && i < array.Length + index; i++) {
104        array.SetValue(this[i], i+index);
105      }
106    }
107    int ICollection.Count { get { return Count;  } }
108
109    public object SyncRoot { get { return this;  } }
110    public bool IsSynchronized { get { return true;  } }
111
112    public int CompareTo(object other, IComparer comparer) {
113      HistoryArray<T> o = other as HistoryArray<T>;
114      if (o == null) return 1;
115      for (int i = 0; i < Count && i < o.Count; i++) {
116        var result = comparer.Compare(this[i], o[i]);
117        if (result != 0)
118          return result;
119      }
120      return Count.CompareTo(o.Count);
121    }
122
123    public bool Equals(object other, IEqualityComparer comparer) {
124      HistoryArray<T> o = other as HistoryArray<T>;
125      if (o == null || o.Count != Count) return false;
126      for (int i = 0; i < Count; i++) {
127        if (!comparer.Equals(this[i], o[i]))
128          return false;
129      }
130      return true;
131    }
132
133    public int GetHashCode(IEqualityComparer comparer) {
134      unchecked { // overflow is fine
135        int hash = (int)2166136261;
136        for (int i = 0; i < Count; i++) {
137          hash = (hash * 16777619) ^ (this[i] == null ? 0 : this[i].GetHashCode());
138        }
139        return hash;
140      }
141    }
142
143    public void Resize(int newSize) {
144      for (int i = newSize; i < Count; i++) {
145        amt.Remove((UInt32)i);
146      }
147      Count = newSize;
148    }
149
150    public void CreateSnapshot() {
151      amt.CreateSnapshot();
152    }
153
154    public IEnumerable<HistoryArray<T>> GetHistory() {
155      yield return this;
156      var prev = amt.Rollback();
157      while (prev != null) {
158        yield return new HistoryArray<T>(prev);
159        prev = prev.Rollback();
160      }
161    }
162  }
163}
Note: See TracBrowser for help on using the repository browser.