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

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

#2727 completely replace basic array with array mapped trie in ValueTypeArray and descendants

File size: 4.2 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    [Storable]
16    public int Count { get; private set; }
17    public int Length { get { return Count; } }
18
19    [StorableConstructor]
20    protected HistoryArray(bool isDeserializing) { }
21
22    protected HistoryArray(HistoryArray<T> orig) {
23      amt = orig.amt.Clone();
24      Count = orig.Count;
25    }
26
27    public HistoryArray(int size) {
28      amt = new ArrayMappedTrie<T>();
29      Count = size;
30    }
31
32    public HistoryArray(IEnumerable<T> elements) {
33      amt = new ArrayMappedTrie<T>();
34      Count = 0;
35      foreach (var element in elements) {
36        Add(element);
37      }
38    }
39
40    public T this[int index] {
41      get {
42        if (index < 0 || index >= Count) throw new IndexOutOfRangeException();
43        return amt[(UInt32) index];
44      }
45      set {
46        if (index < 0 || index >= Count) throw new IndexOutOfRangeException();
47        amt[(UInt32) index] = value;
48      }
49    }
50
51    IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
52
53    public IEnumerator<T> GetEnumerator() {
54      for (int i = 0; i < Count; i++) {
55        yield return this[i];
56      }
57    }
58
59    public object Clone() { return new HistoryArray<T>(this); }
60    public void Add(T item) { amt[(UInt32)Count] = item; Count++; }
61
62    public void Clear() {
63      var oldInterval = amt.SnapshotInterval;
64      amt.SnapshotInterval = 0;
65      for (int i = 0; i < Count; i++)
66        this[i] = default(T);
67      amt.SnapshotInterval = oldInterval;
68      if (oldInterval > 0)
69        amt.CreateSnapshot();
70    }
71    public bool Contains(T item) { return amt.Any(i => i.Equals(item)); }
72
73    public void CopyTo(T[] array, int arrayIndex) {
74      for (int i = 0; i < Count && i+arrayIndex < array.Length; i++) {
75        array[i + arrayIndex] = this[i];
76      }
77    }
78
79    public bool Remove(T item) { throw new NotSupportedException(); }
80    int ICollection<T>.Count { get { return Count;  } }
81
82    public bool IsReadOnly { get { return false;  } }
83    public int IndexOf(T item) {
84      for (int i = 0; i < Count; i++) {
85        if (this[i].Equals(item)) return i;
86      }
87      return -1;
88    }
89    public void Insert(int index, T item) { throw new NotSupportedException(); }
90    public void RemoveAt(int index) { throw new NotSupportedException(); }
91
92    public void CopyTo(Array array, int index) {
93      for (int i = 0; i < Count && i < array.Length + index; i++) {
94        array.SetValue(this[i], i+index);
95      }
96    }
97    int ICollection.Count { get { return Count;  } }
98
99    public object SyncRoot { get { return this;  } }
100    public bool IsSynchronized { get { return true;  } }
101
102    public int CompareTo(object other, IComparer comparer) {
103      HistoryArray<T> o = other as HistoryArray<T>;
104      if (o == null) return 1;
105      for (int i = 0; i < Count && i < o.Count; i++) {
106        var result = comparer.Compare(this[i], o[i]);
107        if (result != 0)
108          return result;
109      }
110      return Count.CompareTo(o.Count);
111    }
112
113    public bool Equals(object other, IEqualityComparer comparer) {
114      HistoryArray<T> o = other as HistoryArray<T>;
115      if (o == null || o.Count != Count) return false;
116      for (int i = 0; i < Count; i++) {
117        if (!comparer.Equals(this[i], o[i]))
118          return false;
119      }
120      return true;
121    }
122
123    public int GetHashCode(IEqualityComparer comparer) {
124      unchecked { // overflow is fine
125        int hash = (int)2166136261;
126        for (int i = 0; i < Count; i++) {
127          hash = (hash * 16777619) ^ (this[i]?.GetHashCode() ?? 0);
128        }
129        return hash;
130      }
131    }
132
133    public void Resize(int newSize) {
134      for (int i = newSize; i < Count; i++) {
135        amt.Remove((UInt32)i);
136      }
137      Count = newSize;
138    }
139  }
140}
Note: See TracBrowser for help on using the repository browser.