23 using System.Collections;
24 using System.Collections.Generic;
26 namespace Lucene.Net.Support
56 public class HashMap<TKey, TValue> : IDictionary<TKey, TValue>
58 internal IEqualityComparer<TKey> _comparer;
59 internal Dictionary<TKey, TValue> _dict;
62 private bool _hasNullValue;
64 private TValue _nullValue;
66 private bool _isValueType;
72 public HashMap(IEqualityComparer<TKey> comparer)
78 public HashMap(
int initialCapacity)
79 : this(initialCapacity, EqualityComparer<TKey>.Default)
84 public HashMap(
int initialCapacity, IEqualityComparer<TKey> comparer)
87 _dict =
new Dictionary<TKey, TValue>(initialCapacity, _comparer);
88 _hasNullValue =
false;
90 if (typeof(TKey).IsValueType)
92 _isValueType = Nullable.GetUnderlyingType(typeof(TKey)) == null;
96 public HashMap(IEnumerable<KeyValuePair<TKey, TValue>> other)
99 foreach (var kvp
in other)
101 Add(kvp.Key, kvp.Value);
105 public bool ContainsValue(TValue value)
107 if (!_isValueType && _hasNullValue && _nullValue.Equals(value))
110 return _dict.ContainsValue(value);
113 #region Implementation of IEnumerable
115 public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
117 if (!_isValueType && _hasNullValue)
119 yield
return new KeyValuePair<TKey, TValue>(
default(TKey), _nullValue);
121 foreach (var kvp
in _dict)
127 IEnumerator IEnumerable.GetEnumerator()
129 return GetEnumerator();
134 #region Implementation of ICollection<KeyValuePair<TKey,TValue>>
136 void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
138 Add(item.Key, item.Value);
143 _hasNullValue =
false;
144 _nullValue =
default(TValue);
148 bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item)
150 if (!_isValueType && _comparer.Equals(item.Key,
default(TKey)))
152 return _hasNullValue && EqualityComparer<TValue>.Default.Equals(item.Value, _nullValue);
155 return ((ICollection<KeyValuePair<TKey, TValue>>)_dict).Contains(item);
158 void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array,
int arrayIndex)
160 ((ICollection<KeyValuePair<TKey, TValue>>) _dict).CopyTo(array, arrayIndex);
161 if(!_isValueType && _hasNullValue)
163 array[array.Length - 1] =
new KeyValuePair<TKey, TValue>(
default(TKey), _nullValue);
167 public bool Remove(KeyValuePair<TKey, TValue> item)
169 if (!_isValueType && _comparer.Equals(item.Key,
default(TKey)))
174 _hasNullValue =
false;
175 _nullValue =
default(TValue);
179 return ((ICollection<KeyValuePair<TKey, TValue>>)_dict).Remove(item);
184 get {
return _dict.Count + (_hasNullValue ? 1 : 0); }
187 public bool IsReadOnly
189 get {
return false; }
194 #region Implementation of IDictionary<TKey,TValue>
196 public bool ContainsKey(TKey key)
198 if (!_isValueType && _comparer.Equals(key,
default(TKey)))
207 return _dict.ContainsKey(key);
210 public virtual void Add(TKey key, TValue value)
212 if (!_isValueType && _comparer.Equals(key,
default(TKey)))
214 _hasNullValue =
true;
223 public bool Remove(TKey key)
225 if (!_isValueType && _comparer.Equals(key,
default(TKey)))
227 _hasNullValue =
false;
228 _nullValue =
default(TValue);
233 return _dict.Remove(key);
237 public bool TryGetValue(TKey key, out TValue value)
239 if (!_isValueType && _comparer.Equals(key,
default(TKey)))
247 value =
default(TValue);
252 return _dict.TryGetValue(key, out value);
256 public TValue
this[TKey key]
260 if (!_isValueType && _comparer.Equals(key,
default(TKey)))
264 return default(TValue);
268 return _dict.ContainsKey(key) ? _dict[key] :
default(TValue);
270 set { Add(key, value); }
273 public ICollection<TKey> Keys
277 if (!_hasNullValue)
return _dict.Keys;
282 return new NullKeyCollection(_dict);
286 public ICollection<TValue> Values
290 if (!_hasNullValue)
return _dict.Values;
295 return new NullValueCollection(_dict, _nullValue);
301 #region NullValueCollection
307 class NullValueCollection : ICollection<TValue>
309 private readonly TValue _nullValue;
310 private readonly Dictionary<TKey, TValue> _internalDict;
312 public NullValueCollection(Dictionary<TKey, TValue> dict, TValue nullValue)
314 _internalDict = dict;
315 _nullValue = nullValue;
318 #region Implementation of IEnumerable
320 public IEnumerator<TValue> GetEnumerator()
322 yield
return _nullValue;
324 foreach (var val
in _internalDict.Values)
330 IEnumerator IEnumerable.GetEnumerator()
332 return GetEnumerator();
337 #region Implementation of ICollection<TValue>
339 public void CopyTo(TValue[] array,
int arrayIndex)
341 throw new NotImplementedException(
"Implement as needed");
346 get {
return _internalDict.Count + 1; }
349 public bool IsReadOnly
354 #region Explicit Interface Methods
356 void ICollection<TValue>.Add(TValue item)
358 throw new NotSupportedException();
361 void ICollection<TValue>.Clear()
363 throw new NotSupportedException();
366 bool ICollection<TValue>.Contains(TValue item)
368 throw new NotSupportedException();
371 bool ICollection<TValue>.Remove(TValue item)
373 throw new NotSupportedException(
"Collection is read only!");
382 #region NullKeyCollection
387 class NullKeyCollection : ICollection<TKey>
389 private readonly Dictionary<TKey, TValue> _internalDict;
391 public NullKeyCollection(Dictionary<TKey, TValue> dict)
393 _internalDict = dict;
396 public IEnumerator<TKey> GetEnumerator()
398 yield
return default(TKey);
399 foreach (var key
in _internalDict.Keys)
405 IEnumerator IEnumerable.GetEnumerator()
407 return GetEnumerator();
410 public void CopyTo(TKey[] array,
int arrayIndex)
412 throw new NotImplementedException(
"Implement this as needed");
417 get {
return _internalDict.Count + 1; }
420 public bool IsReadOnly
425 #region Explicit Interface Definitions
426 bool ICollection<TKey>.Contains(TKey item)
428 throw new NotSupportedException();
431 void ICollection<TKey>.Add(TKey item)
433 throw new NotSupportedException();
436 void ICollection<TKey>.Clear()
438 throw new NotSupportedException();
441 bool ICollection<TKey>.Remove(TKey item)
443 throw new NotSupportedException();