Changeset 3946
- Timestamp:
- 06/24/10 15:35:56 (14 years ago)
- Location:
- trunk/sources/HeuristicLab.Persistence/3.3
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/CompactNumberArray2StringSerializer.cs
r3937 r3946 34 34 35 35 [StorableClass] 36 internal sealed class CompactNumberArray2StringSerializer : ICompositeSerializer { 36 public sealed class CompactNumberArray2StringSerializer : ICompositeSerializer { 37 38 public const int SPLIT_THRESHOLD = 1024 * 1024; 37 39 38 40 public int Priority { … … 60 62 int[] lengths = new int[a.Rank]; 61 63 int[] lowerBounds = new int[a.Rank]; 62 StringBuilder sb = new StringBuilder(a.Rank * 3);64 StringBuilder sb = new StringBuilder(a.Rank * 6); 63 65 sb.Append(a.Rank).Append(';'); 64 int capacity = 1;65 66 for (int i = 0; i < a.Rank; i++) { 66 67 sb.Append(a.GetLength(i)).Append(';'); 67 68 lengths[i] = a.GetLength(i); 68 capacity *= lengths[i];69 69 } 70 sb.EnsureCapacity(capacity * 3);71 70 for (int i = 0; i < a.Rank; i++) { 72 71 sb.Append(a.GetLowerBound(i)).Append(';'); 73 72 lowerBounds[i] = a.GetLowerBound(i); 74 73 } 74 yield return new Tag(sb.ToString()); 75 int nElements = 1; 76 for (int i = 0; i < a.Rank; i++) { 77 lowerBounds[i] = a.GetLowerBound(i); 78 lengths[i] = a.GetLength(i); 79 nElements *= lengths[i]; 80 } 81 sb = new StringBuilder(Math.Min(nElements * 3, SPLIT_THRESHOLD)); 75 82 int[] positions = (int[])lowerBounds.Clone(); 76 83 while (positions[a.Rank - 1] < lengths[a.Rank - 1] + lowerBounds[a.Rank - 1]) { 77 84 sb.Append(numberConverter.Format(a.GetValue(positions))).Append(';'); 85 if (sb.Length > SPLIT_THRESHOLD && sb.Length > sb.Capacity - 18) { 86 yield return new Tag(sb.ToString()); 87 sb = new StringBuilder(Math.Min(nElements * 3, SPLIT_THRESHOLD)); 88 } 78 89 positions[0] += 1; 79 90 for (int i = 0; i < a.Rank - 1; i++) { … … 86 97 } 87 98 } 88 yield return new Tag("compact array", sb.ToString()); 99 if (sb.Length > 0) 100 yield return new Tag(sb.ToString()); 89 101 } 90 102 103 private static Tag[] emptyTag = new Tag[0]; 91 104 public IEnumerable<Tag> Decompose(object obj) { 92 return new Tag[] { };105 return emptyTag; 93 106 } 94 107 … … 99 112 var valueIter = ((string)tagIter.Current.Value).GetSplitEnumerator(';'); 100 113 valueIter.MoveNext(); 101 int rank = int.Parse( (string)valueIter.Current);114 int rank = int.Parse(valueIter.Current); 102 115 int[] lengths = new int[rank]; 103 116 int[] lowerBounds = new int[rank]; 104 117 for (int i = 0; i < rank; i++) { 105 118 valueIter.MoveNext(); 106 lengths[i] = int.Parse( (string)valueIter.Current);119 lengths[i] = int.Parse(valueIter.Current); 107 120 } 108 121 for (int i = 0; i < rank; i++) { 109 122 valueIter.MoveNext(); 110 lowerBounds[i] = int.Parse( (string)valueIter.Current);123 lowerBounds[i] = int.Parse(valueIter.Current); 111 124 } 112 125 Type elementType = type.GetElementType(); 113 126 Array a = Array.CreateInstance(elementType, lengths, lowerBounds); 127 if (a == null) throw new PersistenceException("invalid instance data type, expected array"); 114 128 int[] positions = (int[])lowerBounds.Clone(); 115 while (valueIter.MoveNext()) { 116 a.SetValue( 117 numberConverter.Parse((string)valueIter.Current, elementType), 118 positions); 119 positions[0] += 1; 120 for (int i = 0; i < rank - 1; i++) { 121 if (positions[i] >= lengths[i] + lowerBounds[i]) { 122 positions[i + 1] += 1; 123 positions[i] = lowerBounds[i]; 124 } else { 125 break; 129 while (tagIter.MoveNext()) { 130 valueIter = ((string)tagIter.Current.Value).GetSplitEnumerator(';'); 131 while (valueIter.MoveNext()) { 132 a.SetValue(numberConverter.Parse(valueIter.Current, elementType), positions); 133 positions[0] += 1; 134 for (int i = 0; i < a.Rank - 1; i++) { 135 if (positions[i] >= lengths[i] + lowerBounds[i]) { 136 positions[i + 1] += 1; 137 positions[i] = lowerBounds[i]; 138 } else { 139 break; 140 } 126 141 } 127 142 } … … 129 144 return a; 130 145 } catch (InvalidOperationException e) { 131 throw new PersistenceException("Insuffic ient data to deserialize compact array", e);146 throw new PersistenceException("Insuffictient data to deserialize compact array", e); 132 147 } catch (InvalidCastException e) { 133 148 throw new PersistenceException("Invalid element data during compact array deserialization", e); … … 136 151 137 152 public void Populate(object instance, IEnumerable<Tag> tags, Type type) { 138 // Nothing to do : Compact arrays are already populated during instance creation.153 // Nothing to do. Arrays are populated during instance creation; 139 154 } 140 155 -
trunk/sources/HeuristicLab.Persistence/3.3/Tests/UseCases.cs
r3937 r3946 1075 1075 } 1076 1076 1077 [TestMethod] 1078 public void TestCompactNumberArraySerializer() { 1079 Random r = new Random(); 1080 double[] a = new double[CompactNumberArray2StringSerializer.SPLIT_THRESHOLD * 2 + 1]; 1081 for (int i = 0; i < a.Length; i++) 1082 a[i] = r.Next(10); 1083 var config = ConfigurationService.Instance.GetDefaultConfig(new XmlFormat()); 1084 config = new Configuration(config.Format, 1085 config.PrimitiveSerializers.Where(s => s.SourceType != typeof(double[])), 1086 config.CompositeSerializers); 1087 XmlGenerator.Serialize(a, tempFile, config); 1088 double[] newA = XmlParser.Deserialize<double[]>(tempFile); 1089 Assert.AreEqual(a.Length, newA.Length); 1090 for (int i = 0; i < a.Rank; i++) { 1091 Assert.AreEqual(a.GetLength(i), newA.GetLength(i)); 1092 Assert.AreEqual(a.GetLowerBound(i), newA.GetLowerBound(i)); 1093 } 1094 for (int i = 0; i < a.Length; i++) { 1095 Assert.AreEqual(a[i], newA[i]); 1096 } 1097 } 1077 1098 1078 1099 [ClassInitialize]
Note: See TracChangeset
for help on using the changeset viewer.