/// <summary> /// Generate in memory. /// </summary> /// <returns></returns> static List<Segment> GenerateList() { /// The whole bunch, or the next bunch, of segments. AllSegments = new List<Segment>(); /// Start with this. /// (Todo: Perhaps read from the database.) long nextAvailableValue = 1L; for (int iteration = 0; iteration < ParametersOfExperiment.NoMoreIterationsThan; iteration++) { // Create the next segment. Segment s = new Segment().CreateNewSegmentOfRandomSize(nextAvailableValue, ParametersOfExperiment.MaxSegmentSize, ParametersOfExperiment.NoLargerValueThan); AllSegments.Add(s); // Split zero or more segments. int numberOfSplits = R.Next(0, ParametersOfExperiment.MaxNumberOfConsecutiveSplits); for (int split = 0; split < numberOfSplits; split++) { // Choose a random segment, split it, and update the list of segments. int xSegmentToSplit = R.Next(1, AllSegments.Count); AllSegments.SplitSegment(xSegmentToSplit); } // Stop if reached the max value. nextAvailableValue += s.Size; if (nextAvailableValue > ParametersOfExperiment.NoLargerValueThan) { break; } } return AllSegments; }
public void TestSegment() { Segment s; s = new Segment(); Assert.IsFalse(s.IsValid); s.CreateWithEndPoints(3, 2); Assert.IsFalse(s.IsValid); Assert.IsFalse(s.Size > 0); s.CreateWithEndPoints(7, 7); Assert.IsTrue(s.IsValid); Assert.AreEqual(1, s.Size); int size = int.MaxValue; // heh s.CreateWithEndPoints(1, size); Assert.IsTrue(s.IsValid); Assert.AreEqual(size, s.Size); // CreateNextSegmentOfRandomSize // TODO }
/// <summary> /// The segment is split into two. /// Left part is corrected (the split point is the new right end); /// right part is appended (the split point is the new left end). /// Null on an error! /// </summary> public static List<Segment> SplitSegment(this List<Segment> list, int indexOfSegmentToSplit) { if (null == list || indexOfSegmentToSplit >= list.Count) { return null; } Segment s = list[indexOfSegmentToSplit]; if (s.Size == 1) { return list; } // cannot split int splitAt = R.Next(0, (int) (s.Right - s.Left)); // size is expected to fit in int // L..R is split as S. This means: // 1) if S < R, let T = S+1. Then: // one segment is L..S // another is T..R // 2) Otherwise, S=R. Let U = S-1 = R-1. Then: // one segment is L..U // another is R..R Segment sAnother = new Segment(); long pointL = s.Left; long pointR = s.Right; long pointS, pointT, pointU; pointS = pointL + splitAt; if (splitAt < s.Size) { pointT = pointS + 1L; sAnother.CreateWithEndPoints(pointT, pointR); s.CreateWithEndPoints(pointL, pointS); } else { pointU = pointR - 1; sAnother.CreateWithEndPoints(pointR, pointR); s.CreateWithEndPoints(pointL, pointU); } // Replace s; add sAnother. list[indexOfSegmentToSplit] = s; list.Add(sAnother); return list; }