| | | 1 | | using System; |
| | | 2 | | using System.Collections; |
| | | 3 | | using System.Collections.Generic; |
| | | 4 | | |
| | | 5 | | namespace Chronicler; |
| | | 6 | | |
| | | 7 | | internal sealed class OrderedStringMap<TValue> : IEnumerable<KeyValuePair<string, TValue>> |
| | | 8 | | { |
| | | 9 | | private readonly List<KeyValuePair<string, TValue>> _entries; |
| | | 10 | | private readonly Dictionary<string, int> _indexes; |
| | | 11 | | |
| | 352 | 12 | | public OrderedStringMap(int capacity, IEqualityComparer<string> comparer) |
| | | 13 | | { |
| | 352 | 14 | | _entries = new List<KeyValuePair<string, TValue>>(capacity); |
| | 352 | 15 | | _indexes = new Dictionary<string, int>(capacity, comparer); |
| | 352 | 16 | | } |
| | | 17 | | |
| | 96 | 18 | | public int Count => _entries.Count; |
| | | 19 | | |
| | | 20 | | public TValue this[string key] |
| | | 21 | | { |
| | 256 | 22 | | set => Set(key, value); |
| | | 23 | | } |
| | | 24 | | |
| | | 25 | | public bool TryGetValue(string key, out TValue value) |
| | | 26 | | { |
| | 77 | 27 | | if (!_indexes.TryGetValue(key, out int index)) |
| | | 28 | | { |
| | 28 | 29 | | value = default!; |
| | 28 | 30 | | return false; |
| | | 31 | | } |
| | | 32 | | |
| | 49 | 33 | | value = _entries[index].Value; |
| | 49 | 34 | | return true; |
| | | 35 | | } |
| | | 36 | | |
| | | 37 | | public bool Remove(string key) |
| | | 38 | | { |
| | 11 | 39 | | if (!_indexes.TryGetValue(key, out int index)) |
| | 1 | 40 | | return false; |
| | | 41 | | |
| | 10 | 42 | | _entries.RemoveAt(index); |
| | 10 | 43 | | _indexes.Remove(key); |
| | | 44 | | |
| | 30 | 45 | | for (int i = index; i < _entries.Count; i++) |
| | 5 | 46 | | _indexes[_entries[i].Key] = i; |
| | | 47 | | |
| | 10 | 48 | | return true; |
| | | 49 | | } |
| | | 50 | | |
| | | 51 | | public IEnumerator<KeyValuePair<string, TValue>> GetEnumerator() |
| | | 52 | | { |
| | 152 | 53 | | return _entries.GetEnumerator(); |
| | | 54 | | } |
| | | 55 | | |
| | | 56 | | IEnumerator IEnumerable.GetEnumerator() |
| | | 57 | | { |
| | 0 | 58 | | return GetEnumerator(); |
| | | 59 | | } |
| | | 60 | | |
| | | 61 | | private void Set(string key, TValue value) |
| | | 62 | | { |
| | 256 | 63 | | if (key == null) |
| | 0 | 64 | | throw new ArgumentNullException(nameof(key)); |
| | | 65 | | |
| | 256 | 66 | | if (_indexes.TryGetValue(key, out int index)) |
| | | 67 | | { |
| | 5 | 68 | | string existingKey = _entries[index].Key; |
| | 5 | 69 | | _entries[index] = new KeyValuePair<string, TValue>(existingKey, value); |
| | 5 | 70 | | return; |
| | | 71 | | } |
| | | 72 | | |
| | 251 | 73 | | _indexes.Add(key, _entries.Count); |
| | 251 | 74 | | _entries.Add(new KeyValuePair<string, TValue>(key, value)); |
| | 251 | 75 | | } |
| | | 76 | | } |