/// <summary> /// Slice this collection to list of collection which can be used to create requests /// </summary> /// <param name="maxGroupLength"></param> /// <param name="maxSpareLength"></param> /// <returns></returns> public List <MTagsCollection> Slice(int maxGroupLength = 100, int maxSpareLength = 0) { //124 - макс // (255 - slaveId - func - start*2 - length*2 - crc*2)/2 = 248/2 = 124 var grouped = new List <MTagsCollection>(); // Для ускорения сортируем // По идее должно быть уже отсортировано Sort((x1, x2) => x1.Begin.CompareTo(x2.Begin)); // Группируем все тэги foreach (var tag in this) { var gp = Nearest(grouped, tag); // Если не нашлось подходящей создаем новую группу if ((gp == null) || (gp.SpareTo(tag) > maxSpareLength)) { gp = new MTagsCollection { tag }; grouped.Add(gp); continue; } gp.Add(tag); } // Разделить по максимальному размеру пакета. Пакеты длиннее, делятся на ~равные интервалы. var spared = new List <MTagsCollection>(); foreach (var g in grouped) { if (g.Length > maxGroupLength) { int optLen = (int)(g.Length / Math.Ceiling(g.Length * 1.0 / maxGroupLength)); for (int i = 0; i < g.Count;) { var newGroup = new MTagsCollection(); while ((i < g.Count) && (newGroup.NewSize(g[i]) <= optLen)) { newGroup.Add(g[i++]); } if (newGroup.Count > 0) { spared.Add(newGroup); } } } else { spared.Add(g); } } return(spared); }
private static MTagsCollection Nearest(List <MTagsCollection> ranges, IRange r) { if (ranges is null) { return(null); } // найдем группу при добавлении в которую её размер меняется минимально MTagsCollection nearestGroup = null; int minIncr = int.MaxValue; foreach (var g in ranges) { var d = g.IncrSize(r); if (minIncr > d) { nearestGroup = g; minIncr = d; } } return(nearestGroup); }