Changeset 1322
- Timestamp:
- 03/10/09 17:10:47 (16 years ago)
- Location:
- branches/New Persistence Exploration/Persistence/Persistence
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/New Persistence Exploration/Persistence/Persistence/NewSerializationTest.cs
r1321 r1322 5 5 using System.IO; 6 6 7 namespace Persistence {7 namespace Persistence.Test { 8 8 9 9 public class Root { 10 11 10 [Storable] 12 11 public int[] i = new int[] { 3, 4, 5, 6 }; … … 40 39 [Storable] 41 40 public string name = "Serial"; 41 } 42 43 public class CloneableRoot { 44 public int[] i = new int[] { 3, 4, 5, 6 }; 45 public string s; 46 public ArrayList intArray = new ArrayList(new int[] { 1, 2, 3 }); 47 public List<int> intList = new List<int>(new int[] { 321, 312, 321 }); 48 public CloneableCustom c; 49 public List<CloneableRoot> selfReferences; 50 public double[,] multiDimArray = new double[,] { { 1, 2, 3 }, { 3, 4, 5 } }; 51 public bool boolean = true; 52 public DateTime dateTime = new DateTime(); 53 public KeyValuePair<string, int> kvp = new KeyValuePair<string, int>("test key", 123); 54 public Dictionary<string, int> dict = new Dictionary<string, int>(); 55 public object Clone(Dictionary<object, object> twins) { 56 if (twins.ContainsKey(this)) 57 return twins[this]; 58 CloneableRoot cr = new CloneableRoot(); 59 twins.Add(this, cr); 60 cr.i = this.i; 61 cr.s = this.s; 62 cr.intArray = new ArrayList(this.intArray); 63 cr.intList = new List<int>(this.intList); 64 cr.c = (CloneableCustom)c.Clone(twins); 65 cr.selfReferences = new List<CloneableRoot>(); 66 for (int i = 0; i < this.selfReferences.Count; i++) { 67 cr.selfReferences.Add(this); 68 } 69 cr.multiDimArray = (double[,])this.multiDimArray.Clone(); 70 cr.dateTime = new DateTime(this.dateTime.Ticks); 71 cr.kvp = new KeyValuePair<string, int>(this.kvp.Key, this.kvp.Value); 72 cr.dict = new Dictionary<string, int>(this.dict); 73 return cr; 74 } 75 } 76 77 public class CloneableCustom { 78 public int i; 79 public CloneableRoot r; 80 public string name = "Serial"; 81 public object Clone(Dictionary<object, object> twins) { 82 if (twins.ContainsKey(this)) 83 return twins[this]; 84 CloneableCustom cc = new CloneableCustom(); 85 twins.Add(this, cc); 86 cc.i = this.i; 87 cc.r = (CloneableRoot)this.r.Clone(twins); 88 cc.name = this.name; 89 return cc; 90 } 42 91 } 43 92 … … 52 101 [Storable] 53 102 private Nullable<double> dbl = null; 103 } 104 105 public class StorableObject { 106 107 [Storable] 108 Dictionary<int, string> dict; 109 110 public void Init() { 111 this.dict = new Dictionary<int, string>(); 112 for (int i = 0; i < 1000000; i++) { 113 dict.Add(i, i.ToString()); 114 } 115 } 116 } 117 118 public class CloneableObject : ICloneable { 119 120 Dictionary<int, string> dict; 121 122 public void Init() { 123 this.dict = new Dictionary<int, string>(); 124 for (int i = 0; i < 1000000; i++) { 125 dict.Add(i, i.ToString()); 126 } 127 } 128 public object Clone() { 129 CloneableObject clone = new CloneableObject(); 130 clone.dict = new Dictionary<int, string>(this.dict); 131 return clone; 132 } 54 133 } 55 134 … … 78 157 DeSerializer deSerializer = new DeSerializer(); 79 158 object o = deSerializer.DeSerialize(parser); 80 Root t = StorableAttribute.Clone(r);159 Root t = CloningFactory.DefaultClone(r); 81 160 Console.Out.WriteLine(Util.AutoFormat(o, true)); 82 161 } … … 96 175 DeSerializer deSerializer = new DeSerializer(); 97 176 object o = deSerializer.DeSerialize(parser); 98 Manager n = StorableAttribute.Clone(m);177 Manager n = CloningFactory.DefaultClone(m); 99 178 Console.Out.WriteLine(Util.AutoFormat(o, true)); 100 179 } 101 180 181 public static void SpeedTest() { 182 StorableObject storable = new StorableObject(); 183 CloneableObject cloneable = new CloneableObject(); 184 Console.Write("initializing..."); 185 storable.Init(); 186 cloneable.Init(); 187 Console.WriteLine("done"); 188 List<StorableObject> storableClones = new List<StorableObject>(); 189 List<CloneableObject> clonableClones = new List<CloneableObject>(); 190 CloningFactory cloningFactory = new CloningFactory(); 191 for (int i = 0; i < 100000; i++) { 192 Console.Write("cloning storable.. "); 193 storableClones.Add(cloningFactory.Clone(storable)); 194 Console.WriteLine(); 195 Console.Write("cloning cloneable.. "); 196 clonableClones.Add((CloneableObject)cloneable.Clone()); 197 Console.WriteLine(); 198 } 199 } 200 201 public static void SpeedTest2() { 202 Root r = new Root(); 203 r.selfReferences = new List<Root>(); 204 r.selfReferences.Add(r); 205 r.selfReferences.Add(r); 206 r.c = new Custom(); 207 r.c.r = r; 208 r.dict.Add("one", 1); 209 r.dict.Add("two", 2); 210 r.dict.Add("three", 3); 211 212 CloneableRoot cr = new CloneableRoot(); 213 cr.selfReferences = new List<CloneableRoot>(); 214 cr.selfReferences.Add(cr); 215 cr.selfReferences.Add(cr); 216 cr.c = new CloneableCustom(); 217 cr.c.r = cr; 218 cr.dict.Add("one", 1); 219 cr.dict.Add("two", 2); 220 cr.dict.Add("three", 3); 221 List<Root> storableClones = new List<Root>(); 222 List<CloneableRoot> clonableClones = new List<CloneableRoot>(); 223 CloningFactory cloningFactory = new CloningFactory(); 224 225 DateTime start = DateTime.Now; 226 Console.Write("cloning storable.. "); 227 for (int i = 0; i < 100000; i++) { 228 storableClones.Add(cloningFactory.Clone(r)); 229 } 230 Console.WriteLine(new TimeSpan(DateTime.Now.Ticks - start.Ticks)); 231 232 start = DateTime.Now; 233 Console.Write("cloning storable again.. "); 234 for (int i = 0; i < 100000; i++) { 235 storableClones.Add(cloningFactory.Clone(r)); 236 } 237 Console.WriteLine(new TimeSpan(DateTime.Now.Ticks - start.Ticks)); 238 239 240 start = DateTime.Now; 241 Console.Write("cloning cloneable.. "); 242 for (int i = 0; i < 100000; i++) { 243 clonableClones.Add((CloneableRoot)cr.Clone(new Dictionary<object, object>())); 244 } 245 Console.WriteLine(new TimeSpan(DateTime.Now.Ticks - start.Ticks)); 246 clonableClones.Clear(); 247 248 } 249 102 250 public static void Main() { 103 Test1(); 104 Test2(); 251 //Test1(); 252 //Test2(); 253 //SpeedTest(); 254 SpeedTest2(); 105 255 Console.In.ReadLine(); 106 256 } -
branches/New Persistence Exploration/Persistence/Persistence/Persistence.csproj
r1281 r1322 13 13 <TargetFrameworkVersion>v3.5</TargetFrameworkVersion> 14 14 <FileAlignment>512</FileAlignment> 15 <StartupObject>Persistence. NewSerializationTest</StartupObject>15 <StartupObject>Persistence.Test.NewSerializationTest</StartupObject> 16 16 </PropertyGroup> 17 17 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> -
branches/New Persistence Exploration/Persistence/Persistence/StorableAttribute.cs
r1321 r1322 45 45 } 46 46 return autoStorableAccessors; 47 }48 49 private static MethodInfo MemberwiseClone;50 51 public static StorableAttribute() {52 foreach (MethodInfo mi in typeof(object).GetMethods(BindingFlags.Instance | BindingFlags.NonPublic)) {53 if (mi.Name == "MemberwiseClone") {54 MemberwiseClone = mi;55 }56 }57 }58 59 public static T Clone<T>(T obj) {60 List<ICompoundSerializer> compoundSerializers =61 InterfaceInstantiatior.InstantiateAll<ICompoundSerializer>();62 return Clone(obj, compoundSerializers);63 }64 65 public static T Clone<T>(T obj, IEnumerable<ICompoundSerializer> compoundSerializers) {66 Dictionary<object, object> twins = new Dictionary<object, object>();67 return Clone(obj, twins, compoundSerializers);68 47 } 69 70 public static T Clone<T>(T obj, Dictionary<object, object> twins, 71 IEnumerable<ICompoundSerializer> compoundSerializers) { 48 } 49 50 class CloningFactory { 51 52 private static CloningFactory instance = new CloningFactory(); 53 54 public static T DefaultClone<T>(T obj) { 55 return instance.Clone(obj); 56 } 57 58 private List<ICompoundSerializer> compoundSerializers; 59 60 public CloningFactory(IEnumerable<ICompoundSerializer> compoundSerializers) { 61 this.compoundSerializers = new List<ICompoundSerializer>(compoundSerializers); 62 } 63 64 public CloningFactory() : 65 this(InterfaceInstantiatior.InstantiateAll<ICompoundSerializer>()) { } 66 67 delegate object CloneMethod(object obj, Dictionary<object, object> twins); 68 69 Dictionary<Type, CloneMethod> cloneMethods = new Dictionary<Type, CloneMethod>(); 70 71 public T Clone<T>(T obj) { 72 Dictionary<object, object> twins = new Dictionary<object, object>(); 73 return Clone(obj, twins); 74 } 75 76 public T Clone<T>(T obj, Dictionary<object, object> twins) { 72 77 if (obj == null) 73 78 return default(T); 79 74 80 ValueType t = obj as ValueType; 75 if (t != null) {81 if (t != null) 76 82 return (T)obj; 77 } 83 78 84 if (twins.ContainsKey(obj)) 79 85 return (T)twins[obj]; 86 80 87 ICloneable c = obj as ICloneable; 81 88 if (c != null) { 82 T newClone = (T)c.Clone(); 89 T newClone = (T)c.Clone(); 83 90 twins[obj] = newClone; 84 91 return newClone; 85 92 } 86 T newInstance = (T)Activator.CreateInstance(obj.GetType()); 87 twins[obj] = newInstance; 88 Dictionary<string, DataMemberAccessor> oldAccessors = GetAutostorableAccessors(obj); 89 if (oldAccessors.Count == 0) { 90 foreach (ICompoundSerializer serializer in compoundSerializers) { 91 if ( serializer.CanSerialize(obj.GetType()) ) { 92 IEnumerable subObjects = serializer.Serialize(obj); 93 IEnumerable clonedSubObjects = Functional.Map(subObjects, 94 (x) => Clone(x, twins, compoundSerializers)); 95 return (T)serializer.DeSerialize(clonedSubObjects, obj.GetType()); 93 94 Type type = obj.GetType(); 95 if (!cloneMethods.ContainsKey(type)) 96 cloneMethods[type] = CreateCloneMethod(type); 97 return (T)cloneMethods[type](obj, twins); 98 } 99 100 private CloneMethod CreateCloneMethod(Type type) { 101 if (type.GetConstructor(new Type[] { type }) != null) 102 return CopyConstructorCloneMethod.Create(type); 103 foreach (ICompoundSerializer serializer in compoundSerializers) 104 if (serializer.CanSerialize(type)) 105 return CompoundSerializerCloneMethod.Create(serializer, type, this); 106 return StorableAccessorCloneMethod.Create(type, this); 107 } 108 109 class CopyConstructorCloneMethod { 110 public static CloneMethod Create(Type type) { 111 return new CopyConstructorCloneMethod(type).method; 112 } 113 private ConstructorInfo constructorInfo; 114 public CopyConstructorCloneMethod(Type type) { 115 this.constructorInfo = type.GetConstructor(new Type[] { type }); 116 } 117 118 object method(object obj, Dictionary<object, object> twins) { 119 object newInstance = constructorInfo.Invoke(new object[] { obj }); 120 twins.Add(obj, newInstance); 121 return newInstance; 122 } 123 } 124 125 class CompoundSerializerCloneMethod { 126 public static CloneMethod Create(ICompoundSerializer serializer, 127 Type type, CloningFactory factory) { 128 return new CompoundSerializerCloneMethod(serializer, type, factory).method; 129 } 130 private ICompoundSerializer serializer; 131 private Type type; 132 private CloningFactory factory; 133 public CompoundSerializerCloneMethod(ICompoundSerializer serializer, 134 Type type, CloningFactory factory) { 135 this.serializer = serializer; 136 this.type = type; 137 this.factory = factory; 138 } 139 object method(object obj, Dictionary<object, object> twins) { 140 return serializer.DeSerialize( 141 Functional.Map( 142 serializer.Serialize(obj), 143 (o) => factory.Clone(o, twins)), 144 type); 145 } 146 } 147 148 class StorableAccessorCloneMethod { 149 150 delegate object Getter(object target); 151 delegate void Setter(object target, object value); 152 153 struct FieldAccessor { 154 public Getter Getter; 155 public Setter Setter; 156 public FieldAccessor(Getter getter, Setter setter) { 157 this.Getter = getter; 158 this.Setter = setter; 159 } 160 } 161 162 private const BindingFlags INSTANCE_MEMBERS = 163 BindingFlags.Instance | 164 BindingFlags.Public | 165 BindingFlags.NonPublic; 166 167 public static CloneMethod Create(Type type, CloningFactory factory) { 168 return new StorableAccessorCloneMethod(type, factory).method; 169 } 170 171 private List<FieldAccessor> fieldAccessors; 172 private CloningFactory factory; 173 174 public StorableAccessorCloneMethod(Type type, CloningFactory factory) { 175 this.factory = factory; 176 this.fieldAccessors = new List<FieldAccessor>(); 177 foreach (MemberInfo memberInfo in type.GetMembers(INSTANCE_MEMBERS)) { 178 foreach (object attribute in memberInfo.GetCustomAttributes(false)) { 179 StorableAttribute autoStorableAttribute = 180 attribute as StorableAttribute; 181 if (autoStorableAttribute != null) { 182 if (memberInfo.MemberType == MemberTypes.Field) { 183 FieldInfo fi = (FieldInfo)memberInfo; 184 fieldAccessors.Add(new FieldAccessor( 185 fi.GetValue, 186 fi.SetValue)); 187 } else if (memberInfo.MemberType == MemberTypes.Property) { 188 PropertyInfo pi = (PropertyInfo)memberInfo; 189 fieldAccessors.Add(new FieldAccessor( 190 (target) => pi.GetValue(target, null), 191 (target, value) => pi.SetValue(target, value, null))); 192 } 193 } 96 194 } 97 195 } 98 // TODO: fallback with memberwise clone? 99 throw new ApplicationException("cannot continue cloning, reached a dead end"); 100 } 101 Dictionary<string, DataMemberAccessor> newAccessors = GetAutostorableAccessors(newInstance); 102 foreach (KeyValuePair<string, DataMemberAccessor> nameAccess in oldAccessors) { 103 newAccessors[nameAccess.Key].Set(Clone(nameAccess.Value.Get(), twins, compoundSerializers)); 104 } 105 return newInstance; 196 } 197 object method(object obj, Dictionary<object, object> twins) { 198 object newInstance = Activator.CreateInstance(obj.GetType()); 199 twins.Add(obj, newInstance); 200 foreach (FieldAccessor fa in this.fieldAccessors) { 201 fa.Setter(newInstance, factory.Clone(fa.Getter(obj), twins)); 202 } 203 return newInstance; 204 } 106 205 } 107 206 } 108 207 109 208 public interface IDataMemberAccessor { 110 209 string Name { get; } … … 200 299 } 201 300 202 203 204 205 301 }
Note: See TracChangeset
for help on using the changeset viewer.