static void CreateTags(TableFragment fragment, out TableFragmentTag startTag, out TableFragmentTag endTag, out int hash) { if (fragment == null) { throw new ArgumentNullException(nameof(fragment)); } var values = fragment._values; var startIndex = 0; var startValue = values[0]; var endIndex = 0; var endValue = values[values.Length - 1]; uint currentHash = 0; var startSet = false; for (var i = 0; i < values.Length; i++) { var val = values[i]; if (!startSet && val != startValue) { startSet = true; startIndex = i; } if (val != endValue) { endIndex = i; } currentHash = unchecked (((currentHash >> 5) | (currentHash << 27)) ^ (uint)val); } startTag = new TableFragmentTag() { Fragment = fragment, EndLen = startSet ? startIndex : values.Length, EndValue = startValue, }; endTag = new TableFragmentTag() { Fragment = fragment, EndLen = startSet ? values.Length - endIndex - 1 : values.Length, EndValue = endValue, }; startTag.Partner = endTag; endTag.Partner = startTag; hash = (int)currentHash; }
/// <remarks> /// check for fragments with the same values, if one is found then combine them, otherwise add startTag to the list. /// </remarks> static bool AddEquivilenceList(List <TableFragmentTag> list, TableFragmentTag startTag) { for (var i = 0; i < list.Count; i++) { var existingTag = list[i]; var existing = existingTag.Fragment; var fragment = startTag.Fragment; if (ValuesEquivilent(existing._values, fragment._values)) { existingTag.Partner.Fragment = existingTag.Fragment = Combine(existing, fragment, existing.Count); return(true); } } list.Add(startTag); return(false); }
/// <summary> /// Replace the TableFragments referenced by the two tags with a single fragment that /// contains their combined values. /// </summary> /// <remarks> /// The end of tag1 will be made to overlap the start of tag2 as far as possible. /// </remarks> static void Combine(TableFragmentTag tag1, TableFragmentTag tag2) { int overlap; if (tag1.EndValue != tag2.EndValue) { overlap = 0; } else { overlap = Math.Min(tag1.EndLen, tag2.EndLen); } var fragment = Combine(tag1.Fragment, tag2.Fragment, overlap); tag1.Partner.Fragment = fragment; tag2.Partner.Fragment = fragment; tag1.Partner.Partner = tag2.Partner; tag2.Partner.Partner = tag1.Partner; }
static int Comparison(TableFragmentTag tag1, TableFragmentTag tag2) { var diff = tag1.EndValue - tag2.EndValue; return(diff != 0 ? diff : tag2.EndLen - tag1.EndLen); }