using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using miew.Debugging; namespace agree { #if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// MarkingArrayTfs : low-impact, flat array edge storage /// </summary> ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public class MarkingArrayTfs : MarkingTfs { /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// construct a MarkingArrayTfs with the specified capacity /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public MarkingArrayTfs(TypeMgr tm, int c) : base(tm) { this.entries = new arr_tfs_entry[c]; c |= 1; while (c % 3 == 0 || c % 5 == 0 || c % 7 == 0) c += 2; this.hidx = new int[c]; for (int i = 0; i < c; i++) hidx[i] = -1; c_entries = 0; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// construct a MarkingArrayTfs from a BootstrapTfs /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public MarkingArrayTfs(BootstrapTfs dtfs) : this(dtfs.tm, dtfs.d.Count) { this.Edge = dtfs.Edge; foreach (var kvp in dtfs.d) { int i_feat = (int)(kvp.Key >> 32); int mark = (int)kvp.Key; Edge e = kvp.Value; if (e.FlagsId < 0) { if (corefs == null) corefs = new Dictionary<Edge, int> { { e, 1 } }; else if (corefs.ContainsKey(e)) corefs[e]++; else corefs.Add(e, 1); } uint v; int dx, cur = hidx[v = (uint)((i_feat << 16) ^ mark) % (uint)hidx.Length]; if (cur == -1 || (dx = mark - entries[cur].mark) < 0 || (dx == 0 && i_feat <= entries[cur].i_feat)) hidx[v] = c_entries; else { int prv; do { prv = cur; cur = entries[cur].next; } while (cur != -1 && ((dx = mark - entries[cur].mark) > 0 || (dx == 0 && i_feat > entries[cur].i_feat))); entries[prv].next = c_entries; } entries[c_entries++] = new arr_tfs_entry { i_feat = i_feat, mark = mark, e = e, next = cur }; } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// construct a MarkingArrayTfs from a BootstrapTfs-style Edge dictionary and coreference overrides from a TargetTfs /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public MarkingArrayTfs( TypeMgr tm, Edge top_edge, IDictionary<UInt64, Edge> edges, int coref_tfsid, Dictionary<Int64, Unification.UnifCoref> u_corefs, ref int c_corefs) : this(tm, edges.Count) { this.Edge = top_edge; foreach (var kvp in edges) { int i_feat = (int)(kvp.Key >> 32); int mark = (int)kvp.Key; Edge e = kvp.Value; if (e.FlagsId < 0) { Unification.UnifCoref uc = u_corefs[((long)coref_tfsid << 32) | (uint)e.Mark]; while (uc.f_redirect) uc = uc.next; if (uc.c_fm == 1) { Edge.Flag nf = e.FlagsId & ~Edge.Flag.Coreference; #if DEBUG uc.single_fm = default(FeatMark); #endif uc.c_fm = 0; c_corefs--; if (nf == 0) continue; e = new Edge(nf, (nf & Edge.Flag.EtmNonBareType) == 0 ? 0 : e.Mark); } else { e = uc.e_cur; if (corefs == null) corefs = new Dictionary<Edge, int> { { e, 1 } }; else if (corefs.ContainsKey(e)) corefs[e]++; else corefs.Add(e, 1); } } uint v; int dx, cur = hidx[v = (uint)((i_feat << 16) ^ mark) % (uint)hidx.Length]; if (cur == -1 || (dx = mark - entries[cur].mark) < 0 || (dx == 0 && i_feat <= entries[cur].i_feat)) hidx[v] = c_entries; else { int prv; do { prv = cur; cur = entries[cur].next; } while (cur != -1 && ((dx = mark - entries[cur].mark) > 0 || (dx == 0 && i_feat > entries[cur].i_feat))); entries[prv].next = c_entries; } entries[c_entries++] = new arr_tfs_entry { i_feat = i_feat, mark = mark, e = e, next = cur }; } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// clone of a MarkingArrayTfs (or derived instance). However, because c_entries is a value type, we currently /// don't allow modifying the source through the clone. /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public MarkingArrayTfs(MarkingArrayTfs to_clone) : base(to_clone.tm, to_clone.Edge) { this.entries = to_clone.entries; //this.corefs = to_clone.corefs; this.coref_tallies = to_clone.coref_tallies; this.hidx = to_clone.hidx; this.c_entries = to_clone.c_entries; this.f_locked = true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// edges /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// [DebuggerBrowsable(DebuggerBrowsableState.Never)] arr_tfs_entry[] entries; int freelist = -1; int c_entries = 0; bool f_locked = false; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// hash-to-index /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// [DebuggerBrowsable(DebuggerBrowsableState.Never)] int[] hidx; //[DebuggerBrowsable(DebuggerBrowsableState.Never)] //Dictionary<Edge, int> corefs; //[DebuggerBrowsable(DebuggerBrowsableState.Never)] //public override int CorefCount { get { return corefs == null ? 0 : corefs.Count; } } //[DebuggerBrowsable(DebuggerBrowsableState.Never)] //public override IDictionary<Edge, int> CorefTallies { get { return corefs; } } public override Tfs Clone() { return c_corefs == 0 ? this : new MarkingArrayTfs(this); } [DebuggerBrowsable(DebuggerBrowsableState.Never)] public override int EdgeCount { get { return c_entries; } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public override bool TryGetEdge(int i_feat, int mark, out Edge e) { Debug.Assert(mark != 0); int ix = hidx[(uint)((i_feat << 16) ^ mark) % (uint)hidx.Length]; if (ix != -1) { arr_tfs_entry ent; int d; do { ent = entries[ix]; if ((d = ent.mark - mark) == 0) d = ent.i_feat - i_feat; if (d == 0) { e = ent.e; return true; } } while (d < 0 && (ix = ent.next) != -1); } e = default(Edge); return false; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public override Edge GetEdge(int i_feat, int mark) { Debug.Assert(mark != 0); int ix = hidx[(uint)((i_feat << 16) ^ mark) % (uint)hidx.Length]; if (ix != -1) { arr_tfs_entry ent; int d; do { ent = entries[ix]; if ((d = ent.mark - mark) == 0) d = ent.i_feat - i_feat; if (d == 0) return ent.e; } while (d < 0 && (ix = ent.next) != -1); } return default(Edge); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public override bool ContainsFeatMark(int i_feat, int mark) { Debug.Assert(mark != 0); int ix = hidx[(uint)((i_feat << 16) ^ mark) % (uint)hidx.Length]; if (ix != -1) { arr_tfs_entry ent; int d; do { ent = entries[ix]; if ((d = ent.mark - mark) == 0) d = ent.i_feat - i_feat; if (d == 0) return true; } while (d < 0 && (ix = ent.next) != -1); } return false; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public override void SetEdge(int i_feat, int mark, Edge e) { Debug.Assert(!f_locked, "Cannot modify Tfs through clone"); Debug.Assert(mark != 0); int ix = hidx[(uint)((i_feat << 16) ^ mark) % (uint)hidx.Length]; if (ix != -1) { arr_tfs_entry ent; int d; do { ent = entries[ix]; if ((d = ent.mark - mark) == 0) d = ent.i_feat - i_feat; if (d == 0) goto got_ix; } while (d < 0 && (ix = ent.next) != -1); } if (c_entries < entries.Length - 1) ix = c_entries++; else if ((ix = freelist) != -1) freelist = entries[ix].next; else throw new Exception(String.Format("{0} is an insufficient allocation for this MarkingArrayTfs", entries.Length)); got_ix: uint v; int dx, cur = hidx[v = (uint)((i_feat << 16) ^ mark) % (uint)hidx.Length]; if (cur == -1 || (dx = mark - entries[cur].mark) < 0 || (dx == 0 && i_feat <= entries[cur].i_feat)) hidx[v] = ix; else { int prv; do { prv = cur; cur = entries[cur].next; } while (cur != -1 && ((dx = mark - entries[cur].mark) > 0 || (dx == 0 && i_feat > entries[cur].i_feat))); entries[prv].next = ix; } entries[ix] = new arr_tfs_entry { i_feat = i_feat, mark = mark, e = e, next = cur }; if (e.FlagsId < 0) { if (corefs == null) corefs = new Dictionary<Edge, int> { { e, 1 } }; else if (corefs.ContainsKey(e)) corefs[e]++; else corefs.Add(e, 1); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public override void AddEdge(int i_feat, int mark, Edge e) { Debug.Assert(mark != 0); Debug.Assert(!ContainsFeatMark(i_feat, mark)); Debug.Assert(!f_locked, "Cannot modify Tfs through clone"); int ix; if (c_entries < entries.Length - 1) ix = c_entries++; else if ((ix = freelist) != -1) freelist = entries[ix].next; else throw new Exception(String.Format("{0} is an insufficient allocation for this MarkingArrayTfs", entries.Length)); uint v; int dx, cur = hidx[v = (uint)((i_feat << 16) ^ mark) % (uint)hidx.Length]; if (cur == -1 || (dx = mark - entries[cur].mark) < 0 || (dx == 0 && i_feat <= entries[cur].i_feat)) hidx[v] = ix; else { int prv; do { prv = cur; cur = entries[cur].next; } while (cur != -1 && ((dx = mark - entries[cur].mark) > 0 || (dx == 0 && i_feat > entries[cur].i_feat))); entries[prv].next = ix; } entries[ix] = new arr_tfs_entry { i_feat = i_feat, mark = mark, e = e, next = cur }; if (e.FlagsId < 0) { if (corefs == null) corefs = new Dictionary<Edge, int> { { e, 1 } }; else if (corefs.ContainsKey(e)) corefs[e]++; else corefs.Add(e, 1); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public unsafe override bool RemoveEdge(int i_feat, int mark) { Debug.Assert(!f_locked, "Cannot modify Tfs through clone"); Debug.Assert(mark != 0); uint v; int ix = hidx[v = (uint)((i_feat << 16) ^ mark) % (uint)hidx.Length]; if (ix != -1) { arr_tfs_entry ent; int d, prv = -1; do { ent = entries[ix]; if ((d = ent.mark - mark) == 0) d = ent.i_feat - i_feat; if (d == 0) { if (ent.e.FlagsId < 0 && --corefs[ent.e] == 0) corefs.Remove(ent.e); if (prv == -1) hidx[v] = ent.next; else entries[prv].next = ent.next; #if DEBUG entries[ix] = default(arr_tfs_entry); #else entries[ix].mark = 0; #endif entries[ix].next = freelist; freelist = ix; c_entries--; return true; } if (d > 0) break; prv = ix; } while ((ix = ent.next) != -1); } return false; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public override bool _ContainsInMark(int mark) { Debug.Assert(mark != 0); for (int i = 0; i < entries.Length; i++) if (entries[i].mark == mark) return true; return false; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public override IEnumerable<FeatMarkEdge> FeatMarkEdges { get { foreach (arr_tfs_entry ent in entries) if (ent.mark != 0) yield return new FeatMarkEdge(ent.i_feat, ent.mark, ent.e); } } }; #endif }