source: branches/PersistentDataStructures/HeuristicLab.Data/3.3/PersistentDataStructures/Adaptations/HistoryList.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.0 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 HistoryList<T> : IList<T>, ICloneable {
12
13    [Storable]
14    private readonly ArrayMappedTrie<T> amt;
15
16    public int Count {
17      get { return (int) amt.MetaInfo; }
18      private set { amt.MetaInfo = value; }
19    }
20
21    [StorableConstructor]
22    protected HistoryList(bool isDesierializing) { }
23
24    private HistoryList(ArrayMappedTrie<T> amt) { this.amt = amt; }
25
26    public HistoryList() {
27      amt = new ArrayMappedTrie<T> { SnapshotInterval = 0 };
28      Count = 0;
29    }
30
31    public HistoryList(HistoryList<T> orig) {
32      amt = orig.amt.Clone();
33      Count = orig.Count;
34    }
35
36
37    [Obsolete]
38    public HistoryList(IEnumerable<T> values) {
39      amt = new ArrayMappedTrie<T> { SnapshotInterval = 0 };
40      Count = 0;
41      foreach (var value in values) Add(value);
42    }
43
44    public T this[int index] {
45      get {
46        if (index < 0 || index >= Count) throw new IndexOutOfRangeException();
47        return amt[(UInt32) index];
48      }
49      set {
50        if (index < 0 || index >= Count) throw new IndexOutOfRangeException();
51        amt[(UInt32) index] = value;
52      }
53    }
54
55    public IEnumerator<T> GetEnumerator() {
56      for (int i = 0; i < Count; i++)
57        yield return amt[(UInt32)i];
58    }
59
60    IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
61
62    public void Add(T item) {
63      amt[(UInt32)Count] = item;
64      Count++;
65    }
66
67    public void Clear() { amt.Clear(); }
68
69    public bool Contains(T item) { return amt.Contains(item); }
70
71    public void CopyTo(T[] array, int arrayIndex) {
72      for (int i = 0; i < Count && i < array.Length + arrayIndex; i++) {
73        array[i + arrayIndex] = this[i];
74      }
75    }
76
77    public bool Remove(T item) {
78      var oldInternval = amt.SnapshotInterval;
79      amt.SnapshotInterval = 0;
80      bool found = false;
81      var wi = 0;
82      for (int i = 0; i < Count; i++) {
83        var value = amt[(UInt32) i];
84        if (!value.Equals(item)) {
85          if (wi < i) amt[(UInt32) wi] = value;
86          wi++;
87        }
88      }
89      found = wi < Count;
90      while (wi < Count) {
91        amt.Remove((UInt32) wi);
92        wi++;
93        Count--;
94      }
95      amt.SnapshotInterval = oldInternval;
96      if (oldInternval > 0)
97        amt.CreateSnapshot();
98      return found;
99    }
100
101    public bool IsReadOnly { get { return false; } }
102
103    public int IndexOf(T item) {
104      for (int i = 0; i < Count; i++) {
105        if (amt[(UInt32)i].Equals(item)) return i;
106      }
107      return -1;
108    }
109
110    public void Insert(int index, T item) {
111      var oldInterval = amt.SnapshotInterval;
112      amt.SnapshotInterval = 0;
113      for (int i = Count; i > index; i--) {
114        amt[(UInt32)i] = amt[(UInt32)i - 1];
115      }
116      amt[(UInt32) index] = item;
117      Count++;
118      amt.SnapshotInterval = oldInterval;
119      if (oldInterval > 0)
120        amt.CreateSnapshot();
121    }
122
123    public void RemoveAt(int index) {
124      var oldInterval = amt.SnapshotInterval;
125      amt.SnapshotInterval = 0;
126      for (int i = index; i < Count; i++) {
127        amt[(UInt32)i] = amt[(UInt32)i + 1];
128      }
129      amt.Remove((UInt32)Count-1);
130      amt.SnapshotInterval = oldInterval;
131      if (oldInterval > 0)
132        amt.CreateSnapshot();
133    }
134
135    public void CreateSnapshot() {
136      amt.CreateSnapshot();
137    }
138
139    public IEnumerable<HistoryList<T>> GetHistory() {
140      yield return this;
141      var prev = amt.Rollback();
142      while (prev != null) {
143        yield return new HistoryList<T>(prev);
144        prev = prev.Rollback();
145      }
146    }
147
148    public object Clone() { return new HistoryList<T>(this); }
149  }
150}
Note: See TracBrowser for help on using the repository browser.