Changeset 1434


Ignore:
Timestamp:
03/26/09 17:56:55 (12 years ago)
Author:
epitzer
Message:

Almost complete solution for correctly handling parent references. (#506)

Location:
branches/New Persistence Exploration/Persistence
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • branches/New Persistence Exploration/Persistence/Persistence/Core/DeSerializer.cs

    r1425 r1434  
    55namespace HeuristicLab.Persistence.Core { 
    66
    7   struct ParentReference { }
     7  public struct ParentReference {}
    88  delegate void Setter(object value); 
    99
     
    1818    }
    1919
    20     public void AddValue(string name, object value) {
    21       customValues.Add(new Tag(name, value));
     20    public void AddValue(string name, object value, List<DeSerializer.Thunk> finalFixes) {
     21      Tag t = new Tag(name, value);
     22      t.finalFixes = finalFixes;
     23      customValues.Add(t);
    2224    }
    2325
     
    3133
    3234    private delegate void Handler(ISerializationToken token);
    33     private delegate void Thunk();
     35    public delegate void Thunk();
    3436
    3537    private readonly Dictionary<int, object> id2obj;
     
    136138
    137139    private void NullHandler(ISerializationToken token) {
    138       NullReferenceToken nil = (NullReferenceToken)token;
    139       SetValue(nil.Name, null);
     140      NullReferenceToken nullToken = (NullReferenceToken)token;
     141      SetValue(nullToken.Name, null);
    140142    }   
    141143
     
    144146        parentStack.Push(new CompositeObject(value));
    145147      } else {       
    146         parentStack.Peek().AddValue(name, value);       
     148        parentStack.Peek().AddValue(name, value, finalFixes);       
    147149      }
    148150    }
  • branches/New Persistence Exploration/Persistence/Persistence/Default/Decomposers/ArrayDecomposer.cs

    r1421 r1434  
    4040      int[] positions = new int[rank];
    4141      while (e.MoveNext()) {
    42         a.SetValue(e.Current.Value, positions);
     42        int[] currentPositions = positions;
     43        e.Current.SafeSet((value) => a.SetValue(value, currentPositions));       
    4344        positions[0] += 1;
    4445        for (int i = 0; i < rank-1; i++) {
  • branches/New Persistence Exploration/Persistence/Persistence/Default/Decomposers/DictionaryDecomposer.cs

    r1421 r1434  
    66
    77namespace HeuristicLab.Persistence.Default.Decomposers {
     8
     9  class DictionaryAdder {
     10
     11    bool keyIsSet, valueIsSet;
     12    object key;
     13    object value;
     14    IDictionary dict;
     15
     16    public DictionaryAdder(IDictionary dict) {
     17      this.dict = dict;
     18      keyIsSet = false;
     19      valueIsSet = false;
     20    }
     21
     22    public void SetKey(object value) {
     23      key = value;
     24      keyIsSet = true;
     25      check();
     26    }
     27
     28    public void SetValue(object value) {
     29      this.value = value;
     30      valueIsSet = true;
     31      check();
     32    }
     33
     34    private void check() {
     35      if ( keyIsSet && valueIsSet )
     36        dict.Add(key, value);
     37    }
     38
     39  }
    840 
    941  public class DictionaryDecomposer : IDecomposer {
     
    2961      IEnumerator<Tag> iter = o.GetEnumerator();
    3062      while (iter.MoveNext()) {
    31         object key = iter.Current.Value;
     63        Tag key = iter.Current;
    3264        iter.MoveNext();
    33         object value = iter.Current.Value;
    34         dict.Add(key, value);
     65        Tag value = iter.Current;
     66        DictionaryAdder da = new DictionaryAdder(dict);
     67        key.SafeSet(da.SetKey);
     68        value.SafeSet(da.SetValue);       
    3569      }
    3670      return dict;
  • branches/New Persistence Exploration/Persistence/Persistence/Default/Decomposers/EnumerableDecomposer.cs

    r1421 r1434  
    77
    88namespace HeuristicLab.Persistence.Default.Decomposers {
    9  
    10   public class EnumerableDecomposer : IDecomposer {
     9
     10  public abstract class EnumerableDecomposer : IDecomposer {
     11
     12    public abstract void PerformAdd(object instance, MethodInfo addMethod, Tag tag);
    1113
    1214    public bool CanDecompose(Type type) {
     
    1921          BindingFlags.NonPublic |
    2022          BindingFlags.Instance,
    21           null, Type.EmptyTypes, null) != null;       
     23          null, Type.EmptyTypes, null) != null;
    2224    }
    2325
     
    2931
    3032    public object CreateInstance(Type type) {
    31       return Activator.CreateInstance(type, true);     
     33      return Activator.CreateInstance(type, true);
    3234    }
    3335
    34     public object Populate(object instance, IEnumerable<Tag> objects, Type type) {
     36    public object Populate(object instance, IEnumerable<Tag> tags, Type type) {
    3537      MethodInfo addMethod = type.GetMethod("Add");
    36       foreach (var pair in objects) {
    37         addMethod.Invoke(instance, new[] {pair.Value});
     38      foreach (var tag in tags) {
     39        PerformAdd(instance, addMethod, tag);       
    3840      }
    3941      return instance;
     
    4244  }
    4345
     46  /// <summary>
     47  /// Does never re-order elements but cannot reconstruct enumerables that directly
     48  /// or indirectly contain references to not-yet-contructed parent objects (e.g. arrays).
     49  /// </summary>
     50  public class SafeEnumerableDecomposer : EnumerableDecomposer {
     51    public override void PerformAdd(object instance, MethodInfo addMethod, Tag tag) {
     52      addMethod.Invoke(instance, new[] { tag.Value });
     53    }
     54  }
     55  /// <summary>
     56  /// May re-order elements if the enumerable contains references to
     57  /// not-yet-constructed parent objects (e.g. arrays).
     58  /// </summary>
     59  public class RobustEnumerableDecomposer : EnumerableDecomposer {
     60     public override void PerformAdd(object instance, MethodInfo addMethod, Tag tag) {
     61      tag.SafeSet((value) => addMethod.Invoke(instance, new[] { value }));
     62    }   
     63  }
     64
    4465}
  • branches/New Persistence Exploration/Persistence/Persistence/Default/Decomposers/KeyValuePairDecomposer.cs

    r1421 r1434  
    55using HeuristicLab.Persistence.Core;
    66using HeuristicLab.Persistence.Interfaces;
     7using System.Reflection;
    78
    89namespace HeuristicLab.Persistence.Default.Decomposers {
     
    2324
    2425    public object CreateInstance(Type type) {
    25       return null;
     26      return Activator.CreateInstance(type, true);
    2627    }
    2728
     
    2930      IEnumerator<Tag> iter = o.GetEnumerator();
    3031      iter.MoveNext();
    31       object key = iter.Current.Value;
     32      FieldInfo keyFieldInfo =
     33        t.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
     34        .Single((fi) => fi.Name == "key");
     35      FieldInfo valueFieldInfo =
     36        t.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
     37        .Single((fi) => fi.Name == "value");
     38      iter.Current.SafeSet((value) => keyFieldInfo.SetValue(instance, value));     
    3239      iter.MoveNext();
    33       object value = iter.Current.Value;
    34       return Activator.CreateInstance(t, new object[] { key, value });     
     40      iter.Current.SafeSet((value) => valueFieldInfo.SetValue(instance, value));
     41      return instance;
    3542    }   
    3643  }
  • branches/New Persistence Exploration/Persistence/Persistence/Default/Decomposers/StorableDecomposer.cs

    r1423 r1434  
    2828
    2929    public object Populate(object instance, IEnumerable<Tag> objects, Type type) {           
    30       var memberDict = new Dictionary<string, object>();     
     30      var memberDict = new Dictionary<string, Tag>();     
    3131      IEnumerator<Tag> iter = objects.GetEnumerator();     
    3232      while (iter.MoveNext()) {
    33         memberDict.Add((string)iter.Current.Name, iter.Current.Value);
     33        memberDict.Add((string)iter.Current.Name, iter.Current);
    3434      }     
    3535      foreach (var mapping in StorableAttribute.GetAutostorableAccessors(instance)) {
    36         if ( memberDict.ContainsKey(mapping.Key) )
    37           mapping.Value.Set(memberDict[mapping.Key]);
    38         else if ( mapping.Value.DefaultValue != null )
     36        if (memberDict.ContainsKey(mapping.Key)) {
     37          memberDict[mapping.Key].SafeSet(mapping.Value.Set);
     38        } else if (mapping.Value.DefaultValue != null) {
    3939          mapping.Value.Set(mapping.Value.DefaultValue);
     40        }
    4041      }
    4142      return instance;
  • branches/New Persistence Exploration/Persistence/Persistence/Interfaces/IDecomposer.cs

    r1419 r1434  
    22using System.Collections;
    33using System.Collections.Generic;
     4using HeuristicLab.Persistence.Core;
    45
    56namespace HeuristicLab.Persistence.Interfaces {
    67
    7   public struct Tag {
    8     public string Name;
    9     public object Value;
     8  public class Tag {
     9    public List<DeSerializer.Thunk> finalFixes;
     10    public string Name { get; private set; }
     11    public object Value;     
     12
    1013    public Tag(string name, object value) {
    11       Name = name;
    12       Value = value;
     14      this.Name = name;
     15      this.Value = value;
    1316    }
    1417    public Tag(object value) {
    15       Name = null;
    16       Value = value;
     18      this.Name = null;
     19      this.Value = value;
     20    }
     21    public void SafeSet(DataMemberAccessor.Setter setter) {
     22      if ( Value != null && Value.GetType() == typeof(ParentReference))
     23        finalFixes.Add(() => setter(Value));
     24      else
     25        setter(Value);
    1726    }
    1827  }
  • branches/New Persistence Exploration/Persistence/Test/NewSerializationTest.cs

    r1429 r1434  
    144144      return clone;
    145145    }
    146   } 
     146  }
     147
     148  public class C {
     149    [Storable]
     150    public C[][] allCs;
     151    public KeyValuePair<List<C>, C> kvpList;
     152  }
    147153
    148154  public class NewSerializationTest {
     
    162168    }
    163169
     170    public static void Test3() {
     171      C c = new C();
     172      C[][] cs = new C[2][];
     173      cs[0] = new C[] { c };
     174      cs[1] = new C[] { c };
     175      c.allCs = cs;
     176      c.kvpList = new KeyValuePair<List<C>, C>(new List<C> { c }, c);
     177      XmlGenerator.Serialize(cs, "test3");
     178      object o = XmlParser.DeSerialize("test3");
     179      Console.Out.WriteLine(Util.AutoFormat(o, true));
     180      Console.WriteLine(ViewOnlyGenerator.Serialize(cs));
     181      Console.WriteLine(ViewOnlyGenerator.Serialize(o));
     182    }
     183
    164184    public static void Test2() {
    165185      Manager m = new Manager();     
     
    190210
    191211
    192     public static void Main() {     
     212    public static void Main() {           
    193213      Test1();     
    194214      //Test2();
     215      Test3();
    195216      //SpeedTest();
    196217      //SpeedTest2();
Note: See TracChangeset for help on using the changeset viewer.