/* Copyright 2008 The 'A Concurrent Hashtable' development team (http://www.codeplex.com/CH/People/ProjectPeople.aspx) This library is licensed under the GNU Library General Public License (LGPL). You should have received a copy of the license along with the source code. If not, an online copy of the license can be found at http://www.codeplex.com/CH/license. */ using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Orvid.Concurrent.Collections { internal interface ITrashable { bool IsGarbage { get; } }; internal struct WeakKey : ITrashable where E : class { public static object NullValue = new object(); public object _elementReference; #region ITrashable Members public bool IsGarbage { get { return ((WeakReference)_elementReference).Target == null; } } public bool GetValue(out E value, bool isWeak) { object obj = isWeak ? ((WeakReference)_elementReference).Target : _elementReference; if (obj == null) { value = default(E); return false; } value = (E)( object.ReferenceEquals(NullValue,obj) ? null : obj ); return true; } public void SetValue(E value, bool isWeak) { var obj = (object)value ?? NullValue; _elementReference = isWeak ? (object)(new WeakReference(obj)) : obj; } #endregion } internal struct StrongKey : ITrashable { public StrongKey(E value) { _element = value; } public E _element; #region ITrashable Members public bool IsGarbage { get { return false; } } #endregion } internal struct KeySegment : ITrashable where E : class where T : ITrashable { public WeakKey _elementReference; public T _tail; #region ITrashable Members public bool IsGarbage { get { return _elementReference.IsGarbage || _tail.IsGarbage; } } public bool GetValue(out E value, bool isWeak) { return _elementReference.GetValue(out value, isWeak); } public void SetValue(E value, bool isWeak) { _elementReference.SetValue(value, isWeak); } #endregion } internal abstract class KeyBase : ITrashable where V : ITrashable { public V _values; public S _strongValue; public int _hash; public abstract bool IsWeak { get; } #region ITrashable Members bool ITrashable.IsGarbage { get { return _values.IsGarbage; } } #endregion } internal abstract class Key : KeyBase, S> where W1 : class { public Key Set(Stacktype h, KeyComparer comparer) { bool isWeak = IsWeak; _values.SetValue(h.Item1, isWeak); _strongValue = h.Item2; _hash = comparer.CalculateHashCode(this); return this; } public Key Set(Tuple t, KeyComparer comparer) { return Set(t.AsStacktype(), comparer); } public bool Get(out Stacktype t) { t = new Stacktype { Item2 = _strongValue }; bool res = _values.GetValue(out t.Item1, IsWeak); return res; } public bool Get(out Tuple t) { Stacktype h; bool res = Get(out h); t = h.AsTuple(); return res; } } internal abstract class Key : KeyBase>, S> where W1 : class where W2 : class { public Key Set(Stacktype h, KeyComparer comparer) { bool isWeak = IsWeak; _values.SetValue(h.Item1, isWeak); _values._tail.SetValue(h.Item2, isWeak); _strongValue = h.Item3; _hash = comparer.CalculateHashCode(this); return this; } public Key Set(Tuple t, KeyComparer comparer) { return Set(t.AsStacktype(), comparer); } public bool Get(out Stacktype t) { t = new Stacktype() { Item3 = _strongValue }; bool isWeak = IsWeak; bool res = _values.GetValue(out t.Item1, isWeak); res = _values._tail.GetValue(out t.Item2, isWeak) && res; return res; } public bool Get(out Tuple t) { Stacktype h; bool res = Get(out h); t = h.AsTuple(); return res; } } internal abstract class Key : KeyBase>>, S> where W1 : class where W2 : class where W3 : class { public Key Set(Stacktype h, KeyComparer comparer) { bool isWeak = IsWeak; _values.SetValue(h.Item1, isWeak); _values._tail.SetValue(h.Item2, isWeak); _values._tail._tail.SetValue(h.Item3, isWeak); _strongValue = h.Item4; _hash = comparer.CalculateHashCode(this); return this; } public Key Set(Tuple t, KeyComparer comparer) { return Set(t.AsStacktype(), comparer); } public bool Get(out Stacktype t) { t = new Stacktype { Item4 = _strongValue }; bool isWeak = IsWeak; bool res = _values.GetValue(out t.Item1, isWeak); res = _values._tail.GetValue(out t.Item2, isWeak) && res; res = _values._tail._tail.GetValue(out t.Item3, isWeak) && res; return res; } public bool Get(out Tuple t) { Stacktype h; bool res = Get(out h); t = h.AsTuple(); return res; } } internal abstract class Key : KeyBase>>>, S> where W1 : class where W2 : class where W3 : class where W4 : class { public Key Set(Stacktype h, KeyComparer comparer) { bool isWeak = IsWeak; _values.SetValue(h.Item1, isWeak); _values._tail.SetValue(h.Item2, isWeak); _values._tail._tail.SetValue(h.Item3, isWeak); _values._tail._tail._tail.SetValue(h.Item4, isWeak); _strongValue = h.Item5; _hash = comparer.CalculateHashCode(this); return this; } public Key Set(Tuple t, KeyComparer comparer) { return Set(t.AsStacktype(), comparer); } public bool Get(out Stacktype t) { t = new Stacktype { Item5 = _strongValue }; bool isWeak = IsWeak; bool res = _values.GetValue(out t.Item1, isWeak); res = _values._tail.GetValue(out t.Item2, isWeak) && res; res = _values._tail._tail.GetValue(out t.Item3, isWeak) && res; res = _values._tail._tail._tail.GetValue(out t.Item4, isWeak) && res; return res; } public bool Get(out Tuple t) { Stacktype h; bool res = Get(out h); t = h.AsTuple(); return res; } } internal class StorageKey : Key where W1 : class { public override bool IsWeak { get { return true; } } } internal class StorageKey : Key where W1 : class where W2 : class { public override bool IsWeak { get { return true; } } } internal class StorageKey : Key where W1 : class where W2 : class where W3 : class { public override bool IsWeak { get { return true; } } } internal class StorageKey : Key where W1 : class where W2 : class where W3 : class where W4 : class { public override bool IsWeak { get { return true; } } } internal class SearchKey : Key where W1 : class { public override bool IsWeak { get { return false; } } } internal class SearchKey : Key where W1 : class where W2 : class { public override bool IsWeak { get { return false; } } } internal class SearchKey : Key where W1 : class where W2 : class where W3 : class { public override bool IsWeak { get { return false; } } } internal class SearchKey : Key where W1 : class where W2 : class where W3 : class where W4 : class { public override bool IsWeak { get { return false; } } } }