#define TARGET_ARGS_DELETE
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Runtime.InteropServices;
using miew.Debugging;
using miew.String;
using miew.Enumerable;
#if ILFUNC
using IlFunc;
#endif
#pragma warning disable 0169
#if NODE_INDEX
namespace agree
{
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
///
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
[DebuggerDisplay("{ToString(),nq}")]
public unsafe struct NodeIndexEntry : IComparable<NodeIndexEntry>
{
static public NodeIndexEntry NoFeature;
static NodeIndexEntry()
{
NoFeature = new NodeIndexEntry { f = 0, i_feat = ushort.MaxValue, out_mark = 0 };
}
public ushort i_feat;
public short out_mark;
public Edge.Flag f;
#if DEBUG
public override string ToString()
{
if (i_feat == ushort.MaxValue)
return " ============ ";
FeatureInfo fi = Grammar._singleton.tm.feat_arr[i_feat];
return String.Format("{0} {1} out_mark: {2} f: {3}", fi.i_feat, fi.feature.ToUpper(), out_mark, Edge._FlagsReport(f, true));
}
#endif
public int CompareTo(NodeIndexEntry other) { return this.i_feat - other.i_feat; }
public static void _quick_sort(NodeIndexEntry* p_base, int left, int right)
{
do
{
int a = left;
int b = right;
int sp = a + ((b - a) >> 1);
if (a != sp)
_swap_if_gt(p_base, a, sp);
if (a != b)
_swap_if_gt(p_base, a, b);
if (sp != b)
_swap_if_gt(p_base, sp, b);
int y = p_base[sp].i_feat;
do
{
while (p_base[a].i_feat < y)
a++;
while (y < p_base[b].i_feat)
b--;
if (a > b)
break;
if (a < b)
{
NodeIndexEntry _t = p_base[a];
p_base[a] = p_base[b];
p_base[b] = _t;
}
a++;
b--;
}
while (a <= b);
if ((b - left) <= (right - a))
{
if (left < b)
_quick_sort(p_base, left, b);
left = a;
}
else
{
if (a < right)
_quick_sort(p_base, a, right);
right = b;
}
}
while (left < right);
}
static void _swap_if_gt(NodeIndexEntry* p_base, int i0, int i1)
{
NodeIndexEntry* pnie0, pnie1;
NodeIndexEntry nie0, nie1;
if ((nie0 = *(pnie0 = p_base + i0)).i_feat > (nie1 = *(pnie1 = p_base + i1)).i_feat)
{
*pnie0 = nie1;
*pnie1 = nie0;
}
}
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
///
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public unsafe struct NodeIndex
{
public static int NodeSize(int c_entries, int c_mark_range, int c_in_mark_usage)
{
int c = sizeof(NodeIndex);
c += sizeof(NodeIndexEntry*) * (c_mark_range + 1);
c += sizeof(NodeIndexEntry) * (c_entries + c_in_mark_usage);
return c;
}
public int add_to_mark;
public int c_limit;
public int c_entries;
public int c_in_mark_usage;
public int c_mark_range;
public int _spare;
///
/// ... NodeIndexEntry*[0 ... c_mark_range]
///
/// ... NodeIndexEntry[0 ... ]
///
#if DEBUG
public _debug_node_index_entry[] _entries
{
get
{
int c_limit = c_entries + c_in_mark_usage;
_debug_node_index_entry[] rg = new _debug_node_index_entry[c_limit];
fixed (NodeIndex* _this = &this)
{
NodeIndexEntry** ppnie = (NodeIndexEntry**)(_this + 1);
NodeIndexEntry* pnie_cur = (NodeIndexEntry*)&ppnie[c_mark_range];
for (int i = 0; i < c_limit; i++)
{
ushort ix;
for (ix = 0; ix < c_mark_range; ix++)
if (ppnie[ix] == pnie_cur)
goto found;
ix = ushort.MaxValue;
found:
rg[i] = new _debug_node_index_entry(pnie_cur, ix, ix - add_to_mark);
pnie_cur++;
}
}
return rg;
}
}
[DebuggerDisplay("{ToString(),nq}")]
public unsafe struct _debug_node_index_entry
{
NodeIndexEntry* pnie;
int m;
ushort ix;
public _debug_node_index_entry(NodeIndexEntry* pnie, ushort ix, int m)
{
this.pnie = pnie;
this.m = m;
this.ix = ix;
}
public override string ToString()
{
if (pnie->i_feat == ushort.MaxValue)
return " ============ ";
String z = "";
if (ix != ushort.MaxValue)
z = String.Format("{0}/{1}", ix, m);
FeatureInfo fi = Grammar._singleton.tm.feat_arr[pnie->i_feat];
return String.Format("{0,6} {1} {2} out_mark: {3} f: {4}", z,
fi.i_feat, fi.feature.ToUpper(), pnie->out_mark, Edge._FlagsReport(pnie->f, true));
}
};
#endif
};
public unsafe partial class ArrayTfs : Tfs
{
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
///
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void BuildNodeIndex(Allocator ctrl, int c_actual, int next_mark, int next_coref_mark, int min_coref_in_mark, bool f_sort)
{
min_coref_in_mark = -min_coref_in_mark;
int fpt = tm.fcm.MaxFeaturesPerType;
int c_mark_range = min_coref_in_mark + next_mark;
int c_in_mark_usage = 0;
int* nie_feat_counts = stackalloc int[c_mark_range];
NodeIndexEntry* nie_base = stackalloc NodeIndexEntry[fpt * c_mark_range];
fixed (arr_tfs_entry* _base = entries)
{
arr_tfs_entry* end = _base + c_actual;
for (arr_tfs_entry* dst = _base; dst < end; dst++)
{
int ient = dst->mark + min_coref_in_mark;
int c_cur;
if ((c_cur = nie_feat_counts[ient]++) == 0)
c_in_mark_usage++;
NodeIndexEntry* _pnie = nie_base + (ient * fpt) + c_cur;
//_pnie->arr_ix = (short)i;
_pnie->i_feat = (ushort)dst->i_feat;
_pnie->out_mark = (short)dst->e_Mark;
_pnie->f = dst->e_FlagsId;
}
}
int c_ni_alloc = NodeIndex.NodeSize(c_actual, c_mark_range, c_in_mark_usage);
p_node_index = (NodeIndex*)ctrl.Alloc(c_ni_alloc);
NodeIndex* pni = p_node_index;
pni->add_to_mark = min_coref_in_mark;
pni->c_limit = c_mark_range;
pni->c_entries = c_actual;
pni->c_in_mark_usage = c_in_mark_usage;
pni->c_mark_range = c_mark_range;
NodeIndexEntry** ppnie = (NodeIndexEntry**)(pni + 1);
NodeIndexEntry* pnie_dst = (NodeIndexEntry*)&ppnie[c_mark_range];
*(long*)pnie_dst = -1;
pnie_dst++;
for (int i = 0; i < c_mark_range; i++)
{
int c = nie_feat_counts[i];
if (c == 0)
*ppnie = pnie_dst - 1;
else
{
*ppnie = pnie_dst;
NodeIndexEntry* pnie_src = nie_base + (i * fpt);
if (f_sort)
{
if (c == 2)
{
NodeIndexEntry nie0, nie1;
if ((nie0 = pnie_src[0]).i_feat > (nie1 = pnie_src[1]).i_feat)
{
*pnie_dst++ = nie1;
*pnie_dst++ = nie0;
}
else
{
*pnie_dst++ = nie0;
*pnie_dst++ = nie1;
}
}
else if (c == 1)
{
*pnie_dst++ = *pnie_src;
}
else if (c > 1)
{
NodeIndexEntry._quick_sort(pnie_src, 0, c - 1);
for (int j = 0; j < c; j++)
*pnie_dst++ = *pnie_src++;
}
}
else
{
for (int j = 0; j < c; j++)
*pnie_dst++ = *pnie_src++;
}
*(long*)pnie_dst = -1;
pnie_dst++;
}
ppnie++;
}
}
};
}
#endif