/// <summary> /// Creates a list with given conditions /// </summary> private static CircularSortedList <TKey, TValue> PrepareList <TKey, TValue>(int capacity, int startIndex, int count) { CircularSortedList <TKey, TValue> result = new CircularSortedList <TKey, TValue>(capacity); var keys = Reflector.GetField(result, "keys"); Reflector.SetField(keys, "startIndex", startIndex); var values = Reflector.GetField(result, "values"); Reflector.SetField(values, "startIndex", startIndex); for (int i = 0; i < count; i++) { result.Add(i.Convert <TKey>(), i.Convert <TValue>()); } return(result); }
public void SearchTest() { const int capacity = 10_000; CircularSortedList <int, int> cslistShifted = PrepareList <int, int>(capacity, capacity >> 1, capacity); CircularSortedList <int, int> cslist = new CircularSortedList <int, int>(cslistShifted); SortedList <int, int> slist = new SortedList <int, int>(cslist); SortedDictionary <int, int> sdict = new SortedDictionary <int, int>(cslist); CircularSortedList <LongEnum, int> cslistEnumShifted = PrepareList <LongEnum, int>(capacity, 0, capacity); CircularSortedList <LongEnum, int> cslistEnum = new CircularSortedList <LongEnum, int>(cslistEnumShifted); SortedList <LongEnum, int> slistEnum = new SortedList <LongEnum, int>(cslistEnum); SortedDictionary <LongEnum, int> sdictEnum = new SortedDictionary <LongEnum, int>(cslistEnum); new PerformanceTest <bool> { TestName = "Search Test", Iterations = 1_000_000 }
public void Populate() { CircularSortedList <int, int> cslist = new CircularSortedList <int, int>(); // first element Assert.AreEqual(0, cslist.Add(1, 1)); // 1 element, add to last Assert.AreEqual(1, cslist.Add(6, 6)); Assert.IsTrue(cslist.Keys.SequenceEqual(new[] { 1, 6 })); // 1 element, add before last cslist.Remove(1); Assert.AreEqual(0, cslist.Add(1, 1)); Assert.IsTrue(cslist.Keys.SequenceEqual(new[] { 1, 6 })); // 2 elements, add to head Assert.AreEqual(0, cslist.Add(0, 0)); Assert.IsTrue(cslist.Keys.SequenceEqual(new[] { 0, 1, 6 })); // 2 elements, add to middle cslist.Remove(1); Assert.AreEqual(1, cslist.Add(3, 3)); Assert.IsTrue(cslist.Keys.SequenceEqual(new[] { 0, 3, 6 })); // 3 elements, add after middle Assert.AreEqual(2, cslist.Add(4, 4)); Assert.IsTrue(cslist.Keys.SequenceEqual(new[] { 0, 3, 4, 6 })); // 3 elements, add before middle cslist.Remove(4); Assert.AreEqual(1, cslist.Add(2, 2)); Assert.IsTrue(cslist.Keys.SequenceEqual(new[] { 0, 2, 3, 6 })); // > 3 elements, add after the middle Assert.AreEqual(3, cslist.Add(5, 5)); Assert.IsTrue(cslist.Keys.SequenceEqual(new[] { 0, 2, 3, 5, 6 })); // > 3 elements, add before the middle Assert.AreEqual(1, cslist.Add(1, 1)); Assert.IsTrue(cslist.Keys.SequenceEqual(new[] { 0, 1, 2, 3, 5, 6 })); // > 3 elements, add into the middle Assert.AreEqual(4, cslist.Add(4, 4)); Assert.IsTrue(cslist.Keys.SequenceEqual(new[] { 0, 1, 2, 3, 4, 5, 6 })); }
public void PopulateTest() { const int capacity = 10_000; new PerformanceTest { TestName = "Populate Test", Iterations = 100 } .AddCase(() => { var slist = new SortedList <int, string>(capacity); for (int i = 0; i < capacity; i++) { slist.Add(i, null); } }, "Populating SortedList from sorted data") .AddCase(() => { var sdict = new SortedDictionary <int, string>(); for (int i = 0; i < capacity; i++) { sdict.Add(i, null); } }, "Populating SortedDictionary from sorted data") .AddCase(() => { var cslist = new CircularSortedList <int, string>(capacity); for (int i = 0; i < capacity; i++) { cslist.Add(i, null); } }, "Populating CircularSortedList from sorted data") .AddCase(() => { var slist = new SortedList <int, string>(capacity); for (int i = capacity - 1; i >= 0; i--) { slist.Add(i, null); } }, "Populating SortedList from reverse sorted data") .AddCase(() => { var sdict = new SortedDictionary <int, string>(); for (int i = capacity - 1; i >= 0; i--) { sdict.Add(i, null); } }, "Populating SortedDictionary from reverse sorted data") .AddCase(() => { var cslist = new CircularSortedList <int, string>(capacity); for (int i = capacity - 1; i >= 0; i--) { cslist.Add(i, null); } }, "Populating CircularSortedList from reverse sorted data") .DoTest() .DumpResults(Console.Out); new RandomizedPerformanceTest { TestName = "Randomized Populate Test", Iterations = 100 } .AddCase(rnd => { var slist = new SortedList <int, string>(capacity); for (int i = 0; i < capacity; i++) { slist[rnd.Next(Int32.MaxValue)] = null; } }, "Populating SortedList from random data") .AddCase(rnd => { var sdict = new SortedDictionary <int, string>(); for (int i = 0; i < capacity; i++) { sdict[rnd.Next(Int32.MaxValue)] = null; } }, "Populating SortedDictionary from random data") .AddCase(rnd => { var cslist = new CircularSortedList <int, string>(capacity); for (int i = 0; i < capacity; i++) { cslist[rnd.Next(Int32.MaxValue)] = null; } }, "Populating CircularSortedList from random data") .DoTest() .DumpResults(Console.Out); }
public void EnumeratingTest() { const int capacity = 1000; CircularSortedList <int, string> cslistShifted = PrepareList <int, string>(capacity, capacity >> 1, capacity); CircularSortedList <int, string> cslist = new CircularSortedList <int, string>(cslistShifted); SortedList <int, string> slist = new SortedList <int, string>(cslist); SortedDictionary <int, string> sdict = new SortedDictionary <int, string>(cslist); new PerformanceTest { TestName = "Enumeration Test", Iterations = 10000 } .AddCase(() => { foreach (var item in slist) { } }, "Enumerating SortedList") .AddCase(() => { foreach (var item in sdict) { } }, "Enumerating SortedDictionary") .AddCase(() => { foreach (var item in cslist) { } }, "Enumerating CircularSortedList (0-aligned)") .AddCase(() => { foreach (var item in cslistShifted) { } }, "Enumerating CircularSortedList (shifted)") .AddCase(() => { IEnumerable <KeyValuePair <int, string> > e = slist; foreach (var item in e) { } }, "Enumerating SortedList as IEumerable") .AddCase(() => { IEnumerable <KeyValuePair <int, string> > e = sdict; foreach (var item in e) { } }, "Enumerating SortedDictionary as IEumerable") .AddCase(() => { IEnumerable <KeyValuePair <int, string> > e = cslist; foreach (var item in e) { } }, "Enumerating CircularSortedList (0-aligned) as IEumerable") .AddCase(() => { IEnumerable <KeyValuePair <int, string> > e = cslistShifted; foreach (var item in e) { } }, "Enumerating CircularSortedList (shifted) as IEumerable") .AddCase(() => { for (int i = 0; i < slist.Count; i++) { var x = slist.Keys[i]; } }, "Enumerating SortedList.Keys by indexer") .AddCase(() => { for (int i = 0; i < cslist.Count; i++) { var x = cslist.Keys[i]; } }, "Enumerating CircularSortedList.Keys (0-aligned) by indexer") .AddCase(() => { for (int i = 0; i < cslistShifted.Count; i++) { var x = cslistShifted.Keys[i]; } }, "Enumerating CircularSortedList.Keys (shifted) by indexer") .DoTest() .DumpResults(Console.Out); }
object ISerializationSurrogate.SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector) { if (obj == null) { Throw.ArgumentNullException(Argument.obj); } if (info == null) { Throw.ArgumentNullException(Argument.info); } // can occur if the original type was ISerializable and GetObjectData has changed the type to a non-ISerializable one // Example: .NET 4.6 EnumEqualityComparer->ObjectEqualityComparer if (info.MemberCount == 0) { return(obj); } Type type = obj.GetType(); int level; int fieldIndex; // ordering entries because they can be mixed up by BinaryFormatter CircularSortedList <ulong, SerializationEntry> list = new CircularSortedList <ulong, SerializationEntry>(); foreach (SerializationEntry entry in info) { int pos; if ((pos = entry.Name.IndexOf(':')) > 0 && pos < entry.Name.Length - 1) { if (!Int32.TryParse(entry.Name.Substring(0, pos), NumberStyles.HexNumber, NumberFormatInfo.InvariantInfo, out level)) { Throw.SerializationException(Res.BinarySerializationUnexpectedSerializationInfoElement(entry.Name)); } if (!Int32.TryParse(entry.Name.Substring(pos + 1), NumberStyles.HexNumber, NumberFormatInfo.InvariantInfo, out fieldIndex)) { Throw.SerializationException(Res.BinarySerializationUnexpectedSerializationInfoElement(entry.Name)); } list.Add(((ulong)level << 32) | (uint)fieldIndex, entry); } // end of level found else if (entry.Name.Length >= 2 && entry.Name[0] == 'x') { if (!Int32.TryParse(entry.Name.Substring(1), NumberStyles.HexNumber, NumberFormatInfo.InvariantInfo, out level)) { Throw.SerializationException(Res.BinarySerializationUnexpectedSerializationInfoElement(entry.Name)); } list.Add(((ulong)level << 32) | UInt32.MaxValue, entry); } else { Throw.SerializationException(Res.BinarySerializationUnexpectedSerializationInfoElement(entry.Name)); } } FieldInfo[] fields = SerializationHelper.GetSerializableFields(type); level = 0; fieldIndex = 0; foreach (SerializationEntry entry in list.Values) { if (type == Reflector.ObjectType) { Throw.SerializationException(Res.BinarySerializationObjectHierarchyChangedSurrogate(obj.GetType())); } // field found if (entry.Name == level.ToString("X", NumberFormatInfo.InvariantInfo) + ":" + fieldIndex.ToString("X", NumberFormatInfo.InvariantInfo)) { if (fieldIndex >= fields.Length) { Throw.SerializationException(Res.BinarySerializationMissingFieldSurrogate(type, obj.GetType())); } if (!fields[fieldIndex].FieldType.CanAcceptValue(entry.Value)) { Throw.SerializationException(Res.BinarySerializationUnexpectedFieldType(obj.GetType(), entry.Value, type, fields[fieldIndex].Name)); } fields[fieldIndex].Set(obj, entry.Value); fieldIndex += 1; } // end of level found else if (entry.Name == "x" + level.ToString("X", NumberFormatInfo.InvariantInfo)) { level += 1; // ReSharper disable once PossibleNullReferenceException - see first line inside the loop type = type.BaseType; fields = SerializationHelper.GetSerializableFields(type); fieldIndex = 0; } else { Throw.SerializationException(Res.BinarySerializationUnexpectedSerializationInfoElement(entry.Name)); } } if (type != Reflector.ObjectType) { Throw.SerializationException(Res.BinarySerializationObjectHierarchyChangedSurrogate(obj.GetType())); } return(obj); }