using System; using System.Diagnostics; using System.Collections.Generic; using System.Collections.Concurrent; using System.Linq; using glue; using glue.Debugging; using System.Runtime.InteropServices; using glue.Collections.XSpinLock; namespace agree { /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public abstract class HybridTray : Tray, IFreezableTray { public HybridTray(int tix, TypeMgr tm, int last_mark, int next_id) : base(tix, tm, last_mark, next_id) { } public void Freeze() { if (last_frozen_mark != uint.MaxValue) throw new Exception(); last_frozen_mark = (uint)last_mark_issued; } public uint last_frozen_mark = uint.MaxValue; }; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public class HybridTray<T> : HybridTray where T : IDictionary<Int32, Edge> { public HybridTray(int tix, TypeMgr tm, int last_mark, int next_id) : base(tix, tm, last_mark, next_id) { for (int i = 0; i < Pools.Length; i++) Pools[i] = new HybridTrayConstraintPool(this, i); } public override string ToString() { return base.ToString() + typeof(T).ToString(); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// sealed public class HybridTrayConstraintPool : ConstraintPool { public HybridTrayConstraintPool(Tray tr, int i_feat) : base(tr, i_feat) { singl = new Dictionary<Int32, Edge>(); var o = new FalseSharing.Padding2048(); multi = (T)Activator.CreateInstance(typeof(T)); Nop.X(o); } Dictionary<Int32, Edge> singl; T multi; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public override Edge GetEdge(Int32 m) { Debug.Assert(m != 0); Edge c; ((uint)m <= ((HybridTray<T>)tr).last_frozen_mark ? (IDictionary<Int32, Edge>)singl : multi).TryGetValue(m, out c); return c; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public override bool TryGetEdge(int m, out Edge e) { Debug.Assert(m != 0); return ((uint)m <= ((HybridTray<T>)tr).last_frozen_mark ? (IDictionary<Int32, Edge>)singl : multi).TryGetValue(m, out e); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Store the constraint for the specified mark. Handle Edge value semantics properly. /// Allows detached mark to be set for bare or atomic types /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public override void SetEdge(Int32 m, Edge c) { Debug.Assert(m != 0 && m >= tr._protect_mark); ((uint)m <= ((HybridTray<T>)tr).last_frozen_mark ? (IDictionary<Int32, Edge>)singl : multi)[m] = c; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public override void RemoveEdge(Int32 m) { Debug.Assert(m != 0 && m >= tr._protect_mark); ((uint)m <= ((HybridTray<T>)tr).last_frozen_mark ? (IDictionary<Int32, Edge>)singl : multi).Remove(m); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public override bool TryRemoveEdge(Int32 m, out Edge e) { Debug.Assert(m != 0 && m >= tr._protect_mark); IDictionary<Int32,Edge> d = (uint)m <= ((HybridTray<T>)tr).last_frozen_mark ? (IDictionary<Int32, Edge>)singl : multi; return d.TryGetValue(m, out e) ? d.Remove(m) : false; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public override bool ContainsInMark(Int32 m) { Debug.Assert(m != 0); return ((uint)m <= ((HybridTray<T>)tr).last_frozen_mark ? (IDictionary<Int32, Edge>)singl : multi).ContainsKey(m); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public override int Count { get { return singl.Count + multi.Count; } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public override IEnumerable<int> Marks { get { tr.mre_truncate_ok.WaitOne(); return singl.Keys.Concat(multi.Keys); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public override IEnumerable<Edge> Edges { get { tr.mre_truncate_ok.WaitOne(); return singl.Values.Concat(multi.Values); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public override IEnumerable<KeyValuePair<int, Edge>> PoolEdges { get { tr.mre_truncate_ok.WaitOne(); return singl.Concat(multi); } } }; }; }