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
}