PageRenderTime 22ms CodeModel.GetById 10ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

/IronPython_Main/Tools/IronStudio/IronPythonToolsCore/PyAnalysis/Interpreter/SingleDict.cs

#
C# | 167 lines | 124 code | 27 blank | 16 comment | 30 complexity | bddf5b6699f1161b3859cc3bbb77e6a2 MD5 | raw file
  1/* ****************************************************************************
  2 *
  3 * Copyright (c) Microsoft Corporation. 
  4 *
  5 * This source code is subject to terms and conditions of the Apache License, Version 2.0. A 
  6 * copy of the license can be found in the License.html file at the root of this distribution. If 
  7 * you cannot locate the Apache License, Version 2.0, please send an email to 
  8 * ironpy@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
  9 * by the terms of the Apache License, Version 2.0.
 10 *
 11 * You must not remove this notice, or any other, from this software.
 12 *
 13 * ***************************************************************************/
 14
 15using System;
 16using System.Collections.Generic;
 17using System.Linq;
 18using System.Text;
 19using System.Collections;
 20
 21namespace Microsoft.PyAnalysis.Interpreter {
 22    /// <summary>
 23    /// A simple dictionary like object which has efficient storage when there's only a single item in the dictionary.
 24    /// </summary>
 25    struct SingleDict<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>> {
 26        private object _data; // Dictionary<TKey, TValue> or SingleEntry<TKey, TValue>
 27
 28        sealed class SingleDependency {
 29            public readonly TKey Key;
 30            public TValue Value;
 31
 32            public SingleDependency(TKey key, TValue value) {
 33                Key = key;
 34                Value = value;
 35            }
 36        }
 37
 38        internal bool TryGetValue(TKey fromModule, out TValue deps) {
 39            SingleDependency single = _data as SingleDependency;
 40            if (single != null) {
 41                if (single.Key.Equals(fromModule)) {
 42                    deps = single.Value;
 43                    return true;
 44                }
 45                deps = default(TValue);
 46                return false;
 47            }
 48
 49            Dictionary<TKey, TValue> dict = _data as Dictionary<TKey, TValue>;
 50            if (_data != null) {
 51                return dict.TryGetValue(fromModule, out deps);
 52            }
 53
 54            deps = default(TValue);
 55            return false;
 56        }
 57
 58        public TValue this[TKey key] {
 59            get {
 60                TValue res;
 61                if (TryGetValue(key, out res)) {
 62                    return res;
 63                }
 64
 65                throw new KeyNotFoundException();
 66            }
 67            set {
 68                if (_data == null) {
 69                    _data = new SingleDependency(key, value);
 70                    return;
 71                }
 72
 73                SingleDependency single = _data as SingleDependency;
 74                if (single != null) {
 75                    if (single.Key.Equals(key)) {
 76                        single.Value = value;
 77                        return;
 78                    }
 79
 80                    var data = new Dictionary<TKey, TValue>();
 81                    data[single.Key] = single.Value;
 82                    _data = data;
 83                }
 84
 85                Dictionary<TKey, TValue> dict = _data as Dictionary<TKey, TValue>;
 86                if (dict == null) {
 87                    _data = dict = new Dictionary<TKey, TValue>();
 88                }
 89                dict[key] = value;
 90            }
 91        }
 92
 93        internal void Remove(TKey fromModule) {
 94            SingleDependency single = _data as SingleDependency;
 95            if (single != null) {
 96                if (single.Key.Equals(fromModule)) {
 97                    single = null;
 98                }
 99                return;
100            }
101
102            Dictionary<TKey, TValue> dict = _data as Dictionary<TKey, TValue>;
103            if (_data != null) {
104                dict.Remove(fromModule);
105            }
106        }
107
108        public IEnumerable<TValue> Values {
109            get {
110                SingleDependency single = _data as SingleDependency;
111                if (single != null) {
112                    yield return single.Value;
113                }
114
115                Dictionary<TKey, TValue> dict = _data as Dictionary<TKey, TValue>;
116                if (dict != null) {
117                    foreach (var value in dict.Values) {
118                        yield return value;
119                    }
120                }
121            }
122        }
123
124        public int Count {
125            get {
126                SingleDependency single = _data as SingleDependency;
127                if (single != null) {
128                    return 1;
129                }
130
131                Dictionary<TKey, TValue> dict = _data as Dictionary<TKey, TValue>;
132                if (dict != null) {
133                    return dict.Count;
134                }
135
136                return 0;
137            }
138        }
139
140        #region IEnumerable<KeyValuePair<TKey,TValue>> Members
141
142        public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() {
143            SingleDependency single = _data as SingleDependency;
144            if (single != null) {
145                yield return new KeyValuePair<TKey, TValue>(single.Key, single.Value);
146            }
147
148            Dictionary<TKey, TValue> dict = _data as Dictionary<TKey, TValue>;
149            if (dict != null) {
150                foreach (var keyValue in dict) {
151                    yield return keyValue;
152                }
153            }
154        }
155
156        #endregion
157
158        #region IEnumerable Members
159
160        IEnumerator IEnumerable.GetEnumerator() {
161            throw new NotImplementedException();
162        }
163
164        #endregion
165    }
166
167}