#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