Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
12/15/17 13:26:49 (6 years ago)
Author:
jkarder
Message:

#2520: worked on new persistence

  • changed message definitions
  • updated transformers
  • worked on conversions
  • cleaned up
Location:
branches/PersistenceReintegration/HeuristicLab.Persistence/4.0
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Core/ComponentInfo.cs

    r14927 r15529  
    2525  public sealed class ComponentInfo {
    2626    public string Name { get; private set; }
     27    public string FullName { get; private set; }
    2728    public MemberInfo MemberInfo { get; private set; }
    2829    public StorableAttribute StorableAttribute { get; private set; }
     
    3031    public bool Writeable { get; private set; }
    3132
    32     public ComponentInfo(string name, MemberInfo memberInfo, StorableAttribute storableAttribute, bool readable, bool writeable) {
     33    public ComponentInfo(string name, string fullName, MemberInfo memberInfo, StorableAttribute storableAttribute, bool readable, bool writeable) {
    3334      Name = name;
     35      FullName = fullName;
    3436      MemberInfo = memberInfo;
    3537      StorableAttribute = storableAttribute;
  • branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Core/Mapper.cs

    r15509 r15529  
    6060    private Dictionary<object, uint> object2BoxId;
    6161    private Dictionary<uint, object> boxId2Object;
    62     private Index<TypeBox> typeBoxes;
    63 
    6462    private Index<string> strings;
    6563
    66     private Index<BoolArrayBox> boolArrayBoxes;
    67     private Index<IntArrayBox> intArrayBoxes;
    68     private Index<UnsignedIntArrayBox> unsignedIntArrayBoxes;
    69     private Index<LongArrayBox> longArrayBoxes;
    70     private Index<UnsignedLongArrayBox> unsignedLongArrayBoxes;
    71     private Index<FloatArrayBox> floatArrayBoxes;
    72     private Index<DoubleArrayBox> doubleArrayBoxes;
    73 
    74     private Index<DictionaryBox> dictionaryBoxes;
    75     private Index<StorableClassBox> storableClassBoxes;
    76 
    7764    public uint BoxCount { get; private set; }
    78 
    7965
    8066    public Mapper() {
     
    8571      object2BoxId = new Dictionary<object, uint>(new MappingEqualityComparer());
    8672      boxId2Object = new Dictionary<uint, object>();
    87       typeBoxes = new Index<TypeBox>();
    88 
    8973      strings = new Index<string>();
    90 
    91       boolArrayBoxes = new Index<BoolArrayBox>();
    92       intArrayBoxes = new Index<IntArrayBox>();
    93       unsignedIntArrayBoxes = new Index<UnsignedIntArrayBox>();
    94       longArrayBoxes = new Index<LongArrayBox>();
    95       unsignedLongArrayBoxes = new Index<UnsignedLongArrayBox>();
    96       floatArrayBoxes = new Index<FloatArrayBox>();
    97       doubleArrayBoxes = new Index<DoubleArrayBox>();
    98 
    99       dictionaryBoxes = new Index<DictionaryBox>();
    100       storableClassBoxes = new Index<StorableClassBox>();
    10174
    10275      BoxCount = 0;
     
    164137      return o;
    165138    }
    166 
    167     #region Referenced Boxes
    168     #region TypeBoxes
    169     public uint GetTypeBoxId(TypeBox typeBox) { return typeBoxes.GetIndex(typeBox); }
    170     public TypeBox GetTypeBox(uint typeBoxId) { return typeBoxes.GetValue(typeBoxId); }
    171     #endregion
    172 
    173     #region BoolArrayBox
    174     public uint GetBoolArrayBoxId(BoolArrayBox boolArrayBox) { return boolArrayBoxes.GetIndex(boolArrayBox); }
    175     public BoolArrayBox GetBoolArrayBox(uint boolArrayBoxId) { return boolArrayBoxes.GetValue(boolArrayBoxId); }
    176     #endregion
    177 
    178     #region IntArrayBox
    179     public uint GetIntArrayBoxId(IntArrayBox intArrayBox) { return intArrayBoxes.GetIndex(intArrayBox); }
    180     public IntArrayBox GetIntArrayBox(uint intArrayBoxId) { return intArrayBoxes.GetValue(intArrayBoxId); }
    181     #endregion
    182 
    183     #region UnsignedIntArrayBox
    184     public uint GetUnsignedIntArrayBoxId(UnsignedIntArrayBox unsignedIntArrayBox) { return unsignedIntArrayBoxes.GetIndex(unsignedIntArrayBox); }
    185     public UnsignedIntArrayBox GetUnsignedIntArrayBox(uint unsignedIntArrayBoxId) { return unsignedIntArrayBoxes.GetValue(unsignedIntArrayBoxId); }
    186     #endregion
    187 
    188     #region LongArrayBox
    189     public uint GetLongArrayBoxId(LongArrayBox longArrayBox) { return longArrayBoxes.GetIndex(longArrayBox); }
    190     public LongArrayBox GetLongArrayBox(uint longArrayBoxId) { return longArrayBoxes.GetValue(longArrayBoxId); }
    191     #endregion
    192 
    193     #region UnsignedLongArrayBox
    194     public uint GetUnsignedLongArrayBoxId(UnsignedLongArrayBox unsignedLongArrayBox) { return unsignedLongArrayBoxes.GetIndex(unsignedLongArrayBox); }
    195     public UnsignedLongArrayBox GetUnsignedLongArrayBox(uint unsignedLongArrayBoxId) { return unsignedLongArrayBoxes.GetValue(unsignedLongArrayBoxId); }
    196     #endregion
    197 
    198     #region FloatArrayBox
    199     public uint GetFloatArrayBoxId(FloatArrayBox floatArrayBox) { return floatArrayBoxes.GetIndex(floatArrayBox); }
    200     public FloatArrayBox GetFloatArrayBox(uint floatArrayBoxId) { return floatArrayBoxes.GetValue(floatArrayBoxId); }
    201     #endregion
    202 
    203     #region DoubleArrayBox
    204     public uint GetDoubleArrayBoxId(DoubleArrayBox doubleArrayBox) { return doubleArrayBoxes.GetIndex(doubleArrayBox); }
    205     public DoubleArrayBox GetDoubleArrayBox(uint doubleArrayBoxId) { return doubleArrayBoxes.GetValue(doubleArrayBoxId); }
    206     #endregion
    207 
    208     #region DictionaryBox
    209     public uint GetDictionaryBoxId(DictionaryBox dictionaryBox) { return dictionaryBoxes.GetIndex(dictionaryBox); }
    210     public DictionaryBox GetDictionaryBox(uint dictionaryBoxId) { return dictionaryBoxes.GetValue(dictionaryBoxId); }
    211     #endregion
    212 
    213     #region StorableClassBox
    214     public uint GetStorableClassBoxId(StorableClassBox storableClassBox) { return storableClassBoxes.GetIndex(storableClassBox); }
    215     public StorableClassBox GetStorableClassBox(uint storableClassBoxId) { return storableClassBoxes.GetValue(storableClassBoxId); }
    216     #endregion
    217     #endregion
    218139    #endregion
    219140
     
    243164      bundle.TypeGuids.AddRange(mapper.types.GetValues().Select(x => ByteString.CopyFrom(StaticCache.GetGuid(x).ToByteArray())));
    244165      bundle.Boxes.AddRange(mapper.boxId2Box.OrderBy(x => x.Key).Select(x => x.Value));
    245       bundle.TypeBoxes.AddRange(mapper.typeBoxes.GetValues());
    246 
    247166      bundle.Strings.AddRange(mapper.strings.GetValues());
    248 
    249       bundle.BoolArrayBoxes.AddRange(mapper.boolArrayBoxes.GetValues());
    250       bundle.IntArrayBoxes.AddRange(mapper.intArrayBoxes.GetValues());
    251       bundle.UnsignedIntArrayBoxes.AddRange(mapper.unsignedIntArrayBoxes.GetValues());
    252       bundle.LongArrayBoxes.AddRange(mapper.longArrayBoxes.GetValues());
    253       bundle.UnsignedLongArrayBoxes.AddRange(mapper.unsignedLongArrayBoxes.GetValues());
    254       bundle.FloatArrayBoxes.AddRange(mapper.floatArrayBoxes.GetValues());
    255       bundle.DoubleArrayBoxes.AddRange(mapper.doubleArrayBoxes.GetValues());
    256 
    257       bundle.DictionaryBoxes.AddRange(mapper.dictionaryBoxes.GetValues());
    258       bundle.StorableClassBoxes.AddRange(mapper.storableClassBoxes.GetValues());
    259167
    260168      return bundle;
     
    265173      mapper.transformers = new Index<ITransformer>(bundle.TransformerGuids.Select(x => new Guid(x.ToByteArray())).Select(StaticCache.GetTransformer));
    266174      mapper.types = new Index<Type>(bundle.TypeGuids.Select(x => StaticCache.GetType(new Guid(x.ToByteArray()))));
    267 
    268175      mapper.boxId2Box = bundle.Boxes.Select((b, i) => new { Box = b, Index = i }).ToDictionary(k => (uint)k.Index + 1, v => v.Box);
    269       mapper.typeBoxes = new Index<TypeBox>(bundle.TypeBoxes);
    270 
    271176      mapper.strings = new Index<string>(bundle.Strings);
    272 
    273       mapper.boolArrayBoxes = new Index<BoolArrayBox>(bundle.BoolArrayBoxes);
    274       mapper.intArrayBoxes = new Index<IntArrayBox>(bundle.IntArrayBoxes);
    275       mapper.unsignedIntArrayBoxes = new Index<UnsignedIntArrayBox>(bundle.UnsignedIntArrayBoxes);
    276       mapper.longArrayBoxes = new Index<LongArrayBox>(bundle.LongArrayBoxes);
    277       mapper.unsignedLongArrayBoxes = new Index<UnsignedLongArrayBox>(bundle.UnsignedLongArrayBoxes);
    278       mapper.floatArrayBoxes = new Index<FloatArrayBox>(bundle.FloatArrayBoxes);
    279       mapper.doubleArrayBoxes = new Index<DoubleArrayBox>(bundle.DoubleArrayBoxes);
    280 
    281       mapper.dictionaryBoxes = new Index<DictionaryBox>(bundle.DictionaryBoxes);
    282       mapper.storableClassBoxes = new Index<StorableClassBox>(bundle.StorableClassBoxes);
    283177
    284178      return mapper.GetObject(bundle.RootBoxId);
  • branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Core/StaticCache.cs

    r15509 r15529  
    2525using System.Drawing;
    2626using System.Linq;
     27using System.Reflection;
    2728using HeuristicLab.PluginInfrastructure;
    2829
     
    3637    private readonly Dictionary<Type, Guid> type2Guid;
    3738    private readonly Dictionary<Type, TypeInfo> typeInfos;
     39    private readonly Dictionary<Guid, List<MethodInfo>> guid2ConversionMethods;
    3840
    3941    internal StaticCache() {
     
    4345      type2Guid = new Dictionary<Type, Guid>();
    4446      typeInfos = new Dictionary<Type, TypeInfo>();
     47      guid2ConversionMethods = new Dictionary<Guid, List<MethodInfo>>();
    4548
    4649      foreach (var transformer in ApplicationManager.Manager.GetInstances<ITransformer>())
     
    108111            if (StorableTypeAttribute.IsStorableType(t)) {
    109112              RegisterType(StorableTypeAttribute.GetStorableTypeAttribute(t).Guid, t);
     113            }
     114            foreach (var mi in t.GetMethods(BindingFlags.NonPublic | BindingFlags.Static)) {
     115              if (StorableConversionAttribute.IsStorableConversionMethod(mi)) {
     116                RegisterStorableConversion(StorableConversionAttribute.GetStorableConversionAttribute(mi).Guid, mi);
     117              }
    110118            }
    111119          }
     
    149157      }
    150158    }
     159    public void RegisterStorableConversion(Guid guid, MethodInfo methodInfo) {
     160      lock (locker) {
     161        List<MethodInfo> conversionMethods;
     162        if (!guid2ConversionMethods.TryGetValue(guid, out conversionMethods))
     163          guid2ConversionMethods.Add(guid, conversionMethods = new List<MethodInfo>());
     164        conversionMethods.Add(methodInfo);
     165      }
     166    }
    151167
    152168    // mainly for testing
     
    186202      }
    187203    }
     204
     205    public IEnumerable<MethodInfo> GetStorableConversions(Guid guid) {
     206      List<MethodInfo> conversionMethods;
     207      if (guid2ConversionMethods.TryGetValue(guid, out conversionMethods)) return conversionMethods;
     208      return Enumerable.Empty<MethodInfo>();
     209    }
    188210  }
    189211}
  • branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Core/StorableConversionAttribute.cs

    r15034 r15529  
    2727  public sealed class StorableConversionAttribute : Attribute {
    2828    public Guid Guid { get; private set; }
    29     public uint SrcVersion { get; private set; }
     29    public uint Version { get; private set; }
    3030
    31     public StorableConversionAttribute(string guid, uint srcVersion) {
     31    public StorableConversionAttribute(string guid, uint version) {
    3232      this.Guid = new Guid(guid);
    33       this.SrcVersion = srcVersion;
     33      this.Version = version;
    3434    }
    3535
     
    4545    }
    4646    public static uint GetVersion(MethodInfo mi) {
    47       return GetStorableConversionAttribute(mi).SrcVersion;
     47      return GetStorableConversionAttribute(mi).Version;
    4848    }
    4949  }
  • branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Core/TypeInfo.cs

    r15034 r15529  
    5858      StorableTypeAttribute = StorableTypeAttribute.GetStorableTypeAttribute(type);
    5959      if (StorableTypeAttribute != null) {
    60         // check constructors (
     60        string guidPrefix = StorableTypeAttribute.Guid.ToString().ToUpper();
     61        // check constructors
    6162        if (!type.IsValueType && !type.IsEnum && !type.IsInterface &&
    6263          GetStorableConstructor() == null && GetDefaultConstructor() == null)
    6364          throw new PersistenceException("No storable constructor or parameterless constructor found.");
    64 
    65         // traverse type hierarchy from base type to sub types
    66         Stack<Type> types = new Stack<Type>();
    67         while (type != null) {
    68           types.Push(type);
    69           type = type.BaseType;
    70         }
    7165
    7266        var fields = new List<ComponentInfo>();
     
    7468        var beforeSerializationHooks = new List<MethodInfo>();
    7569        var afterDeserializationHooks = new List<MethodInfo>();
    76         while (types.Count > 0) {
    77           type = types.Pop();
    78           if (StorableTypeAttribute.MemberSelection != StorableMemberSelection.AllProperties) {
    79             var fieldInfos = type.GetFields(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic)
    80                                  .Where(x => !x.Name.StartsWith("<") && !x.Name.EndsWith("k__BackingField")); // exclude backing fields
    81             if (StorableTypeAttribute.MemberSelection == StorableMemberSelection.MarkedOnly)
    82               fieldInfos = fieldInfos.Where(x => StorableAttribute.IsStorable(x)).ToArray();
    83             foreach (var field in fieldInfos) {
    84               var attrib = StorableAttribute.GetStorableAttribute(field);
    85               var name = attrib == null || string.IsNullOrEmpty(attrib.Name) ? field.Name : attrib.Name;
    86               fields.Add(new ComponentInfo(type.Name + '.' + name, field, attrib, true, true));
    87             }
    88           }
    8970
    90           if (StorableTypeAttribute.MemberSelection != StorableMemberSelection.AllFields) {
    91             var propertyInfos = type.GetProperties(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic).
    92                         Where(x => x.GetIndexParameters().Length == 0);  // exclude indexed properties
    93             if (StorableTypeAttribute.MemberSelection == StorableMemberSelection.MarkedOnly)
    94               propertyInfos = propertyInfos.Where(x => StorableAttribute.IsStorable(x)).ToArray();
    95             foreach (var property in propertyInfos) {
    96               var attrib = StorableAttribute.GetStorableAttribute(property);
    97               if ((!property.CanRead || !property.CanWrite) && (attrib == null || !attrib.AllowOneWay))
    98                 throw new PersistenceException("Properties must be readable and writable or explicity enable one way serialization.");
     71        if (StorableTypeAttribute.MemberSelection != StorableMemberSelection.AllProperties) {
     72          var fieldInfos = type.GetFields(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic)
     73                               .Where(x => !x.Name.StartsWith("<") && !x.Name.EndsWith("k__BackingField")); // exclude backing fields
    9974
    100               var name = attrib == null || string.IsNullOrEmpty(attrib.Name) ? property.Name : attrib.Name;
    101               properties.Add(new ComponentInfo(type.Name + '.' + name, property, attrib, property.CanRead, property.CanWrite));
    102             }
    103           }
     75          if (StorableTypeAttribute.MemberSelection == StorableMemberSelection.MarkedOnly)
     76            fieldInfos = fieldInfos.Where(StorableAttribute.IsStorable).ToArray();
    10477
    105           var methodInfos = type.GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic).
    106                             Where(x => StorableHookAttribute.IsStorableHook(x)).
    107                             Where(x => (x.ReturnType == typeof(void)) && (x.GetParameters().Length == 0));
    108           foreach (var method in methodInfos) {
    109             foreach (var attrib in StorableHookAttribute.GetStorableHookAttributes(method)) {
    110               if (attrib.HookType == HookType.BeforeSerialization)
    111                 beforeSerializationHooks.Add(method);
    112               if (attrib.HookType == HookType.AfterDeserialization)
    113                 afterDeserializationHooks.Add(method);
    114             }
     78          foreach (var field in fieldInfos) {
     79            var attrib = StorableAttribute.GetStorableAttribute(field);
     80            var name = attrib == null || string.IsNullOrEmpty(attrib.Name) ? field.Name : attrib.Name;
     81            fields.Add(new ComponentInfo(name, guidPrefix + "." + name, field, attrib, true, true));
    11582          }
    11683        }
     84
     85        if (StorableTypeAttribute.MemberSelection != StorableMemberSelection.AllFields) {
     86          var propertyInfos = type.GetProperties(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic)
     87                                  .Where(x => !x.GetIndexParameters().Any());  // exclude indexed properties
     88
     89          if (StorableTypeAttribute.MemberSelection == StorableMemberSelection.MarkedOnly)
     90            propertyInfos = propertyInfos.Where(StorableAttribute.IsStorable).ToArray();
     91
     92          foreach (var property in propertyInfos) {
     93            var attrib = StorableAttribute.GetStorableAttribute(property);
     94            if ((!property.CanRead || !property.CanWrite) && (attrib == null || !attrib.AllowOneWay))
     95              throw new PersistenceException("Properties must be readable and writable or have one way serialization explicitly enabled.");
     96
     97            var name = attrib == null || string.IsNullOrEmpty(attrib.Name) ? property.Name : attrib.Name;
     98            properties.Add(new ComponentInfo(name, guidPrefix + "." + name, property, attrib, property.CanRead, property.CanWrite));
     99          }
     100        }
     101
     102        var methodInfos = type.GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic)
     103                              .Where(StorableHookAttribute.IsStorableHook)
     104                              .Where(x => x.ReturnType == typeof(void) && !x.GetParameters().Any());
     105
     106        foreach (var method in methodInfos) {
     107          foreach (var attrib in StorableHookAttribute.GetStorableHookAttributes(method)) {
     108            if (attrib.HookType == HookType.BeforeSerialization)
     109              beforeSerializationHooks.Add(method);
     110            if (attrib.HookType == HookType.AfterDeserialization)
     111              afterDeserializationHooks.Add(method);
     112          }
     113        }
     114
    117115        Fields = fields;
    118116        Properties = properties;
     
    155153
    156154    private ConstructorInfo GetStorableConstructor() {
    157       return Type.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
    158                .Where(x => StorableConstructorAttribute.IsStorableConstructor(x))
    159                .Where(x => (x.GetParameters().Length == 1) && (x.GetParameters()[0].ParameterType == typeof(StorableConstructorFlag)))
    160                .FirstOrDefault();
     155      return (from ctor in Type.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
     156              let parameters = ctor.GetParameters()
     157              where StorableConstructorAttribute.IsStorableConstructor(ctor)
     158                 && parameters.Length == 1
     159                 && parameters[0].ParameterType == typeof(StorableConstructorFlag)
     160              select ctor).FirstOrDefault();
    161161    }
    162162
    163163    private ConstructorInfo GetDefaultConstructor() {
    164       return Type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
    165                              null, Type.EmptyTypes, null);
     164      return Type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
    166165    }
    167166  }
  • branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Protos/PersistenceMessages.proto

    r15509 r15529  
    99  uint32 root_box_id = 10;
    1010  repeated Box boxes = 20;
    11   repeated TypeBox type_boxes = 30;
     11  repeated string strings = 30;
     12}
    1213
    13   repeated string strings = 100;
    14 
    15   repeated BoolArrayBox bool_array_boxes = 200;
    16   repeated IntArrayBox int_array_boxes = 201;
    17   repeated UnsignedIntArrayBox unsigned_int_array_boxes = 203;
    18   repeated LongArrayBox long_array_boxes = 202;
    19   repeated UnsignedLongArrayBox unsigned_long_array_boxes = 204;
    20   repeated FloatArrayBox float_array_boxes = 205;
    21   repeated DoubleArrayBox double_array_boxes = 206;
    22  
    23   repeated DictionaryBox dictionary_boxes = 300;
    24   repeated StorableClassBox storable_class_boxes = 310;
    25 }
    2614message Box {
    2715  uint32 transformer_id = 1;
    28   uint32 type_id = 2;
    29   uint32 box_id = 3;
     16  uint32 type_box_id = 2;
    3017
    31   bool bool = 10;
    32   int32 int = 11;
    33   int64 long = 12;
    34   uint32 u_int = 13;
    35   uint64 u_long = 14;
    36   float float = 15;
    37   double double = 16;
    38   bytes bytes = 17;
     18  uint32 type_id = 10;
     19  uint32 type_version = 11;
     20  repeated uint32 generic_type_box_ids = 12;
     21
     22  bool bool = 20;
     23  int32 int = 21;
     24  int64 long = 22;
     25  uint32 u_int = 23;
     26  uint64 u_long = 24;
     27  float float = 25;
     28  double double = 26;
     29  bytes bytes = 27;
     30
     31  repeated bool bools = 30;
     32  repeated int32 ints = 31;
     33  repeated int64 longs = 32;
     34  repeated uint32 u_ints = 33;
     35  repeated uint64 u_longs = 34;
     36  repeated float floats = 35;
     37  repeated double doubles = 36;
     38
     39  map<uint32, uint32> key_value_pairs = 40;
     40  uint32 comparer_id = 50;
    3941}
    40 message TypeBox {
    41   uint32 version = 1;
    42   repeated uint32 generic_type_ids = 2;
    43 }
    44 
    45 // array boxes
    46 message StringArrayBox { repeated string values = 1; }
    47 message BoolArrayBox { repeated bool values = 1; }
    48 message IntArrayBox { repeated int32 values = 1; }
    49 message LongArrayBox { repeated int64 values = 1; }
    50 message UnsignedIntArrayBox { repeated uint32 values = 1; }
    51 message UnsignedLongArrayBox { repeated uint64 values = 1; }
    52 message FloatArrayBox { repeated float values = 1; }
    53 message DoubleArrayBox { repeated double values = 1; }
    54 
    55 // matrix boxes
    56 message MatrixBox {
    57   uint32 element_type_id = 1;
    58   repeated uint32 lengths = 2;
    59 }
    60 message BoolMatrixBox {
    61   MatrixBox matrixBox = 1;
    62   repeated bool values = 2;
    63 }
    64 message IntMatrixBox {
    65   MatrixBox matrixBox = 1;
    66   repeated int32 values = 2;
    67 }
    68 
    69 // composite boxes
    70 message DictionaryBox {
    71   map<uint32, uint32> key_value_pairs = 1;
    72   uint32 comparer_id = 2;
    73 }
    74 message StorableClassBox {
    75   map<uint32, uint32> key_value_pairs = 1;
    76 }
  • branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Transformers/Transformers.cs

    r15509 r15529  
    4141      var box = new Box {
    4242        TransformerId = mapper.GetTransformerId(this),
    43         TypeId = mapper.GetBoxId(o.GetType())
     43        TypeBoxId = mapper.GetBoxId(o.GetType())
    4444      };
    4545      Populate(box, (T)o, mapper);
     
    4848
    4949    public override object ToObject(Box box, Mapper mapper) {
    50       return Extract(box, (Type)mapper.GetObject(box.TypeId), mapper);
     50      return Extract(box, (Type)mapper.GetObject(box.TypeBoxId), mapper);
    5151    }
    5252
     
    6363
    6464    public override Box ToBox(object o, Mapper mapper) {
    65       var box = new Box {
    66         TransformerId = mapper.GetTransformerId(this)
    67       };
     65      var box = new Box { TransformerId = mapper.GetTransformerId(this) };
    6866      Populate(box, o, mapper);
    6967      return box;
     
    7270    private void Populate(Box box, object value, Mapper mapper) {
    7371      var type = (Type)value;
    74       var typeBox = new TypeBox();
    7572
    7673      if (type.IsGenericType) {
    7774        box.TypeId = mapper.GetTypeId(type.GetGenericTypeDefinition());
    78         typeBox.GenericTypeIds.AddRange(type.GetGenericArguments().Select(mapper.GetBoxId));
     75        box.GenericTypeBoxIds.AddRange(type.GetGenericArguments().Select(mapper.GetBoxId));
    7976      } else if (type.IsArray) {
    8077        box.TypeId = mapper.GetTypeId(typeof(Array));
    81         typeBox.GenericTypeIds.Add(mapper.GetBoxId(type.GetElementType()));
     78        box.GenericTypeBoxIds.Add(mapper.GetBoxId(type.GetElementType()));
    8279      } else {
    8380        box.TypeId = mapper.GetTypeId(type);
     
    8582
    8683      if (StorableTypeAttribute.IsStorableType(type))
    87         typeBox.Version = StorableTypeAttribute.GetStorableTypeAttribute(type).Version;
    88 
    89       box.BoxId = mapper.GetTypeBoxId(typeBox);
     84        box.TypeVersion = StorableTypeAttribute.GetStorableTypeAttribute(type).Version;
    9085    }
    9186
     
    9590
    9691    private object Extract(Box box, Type type, Mapper mapper) {
    97       var typeBox = mapper.GetTypeBox(box.BoxId);
    98 
    9992      if (type.IsGenericType) {
    100         return type.MakeGenericType(typeBox.GenericTypeIds.Select(id => (Type)mapper.GetObject(id)).ToArray());
     93        return type.MakeGenericType(box.GenericTypeBoxIds.Select(x => (Type)mapper.GetObject(x)).ToArray());
    10194      } else if (type == typeof(Array)) {
    102         return ((Type)mapper.GetObject(typeBox.GenericTypeIds[0])).MakeArrayType();
     95        return ((Type)mapper.GetObject(box.GenericTypeBoxIds[0])).MakeArrayType();
    10396      } else {
    104 
    10597        return type;
    10698      }
     
    202194  [StorableType("4397B775-7D48-4C2A-8D28-ACC8C196CF70")]
    203195  internal sealed class StringArrayBoxTransformer : BoxTransformer<string[]> {
    204     protected override void Populate(Box box, string[] value, Mapper mapper) {
    205       var unsignedIntArrayBox = new UnsignedIntArrayBox();
    206       unsignedIntArrayBox.Values.AddRange(value.Select(mapper.GetStringId));
    207       box.BoxId = mapper.GetUnsignedIntArrayBoxId(unsignedIntArrayBox);
    208     }
    209 
    210     protected override string[] Extract(Box box, Type type, Mapper mapper) {
    211       var unsignedIntArrayBox = mapper.GetUnsignedIntArrayBox(box.BoxId);
    212       return unsignedIntArrayBox.Values.Select(mapper.GetString).ToArray();
    213     }
     196    protected override void Populate(Box box, string[] value, Mapper mapper) { box.UInts.AddRange(value.Select(mapper.GetStringId)); }
     197    protected override string[] Extract(Box box, Type type, Mapper mapper) { return box.UInts.Select(mapper.GetString).ToArray(); }
    214198  }
    215199
     
    217201  [StorableType("9719DB59-C6BC-4788-BBB0-389A1B49CFEE")]
    218202  internal sealed class BoolArrayBoxTransformer : BoxTransformer<bool[]> {
    219     protected override void Populate(Box box, bool[] value, Mapper mapper) {
    220       var boolArrayBox = new BoolArrayBox();
    221       boolArrayBox.Values.AddRange(value);
    222       box.BoxId = mapper.GetBoolArrayBoxId(boolArrayBox);
    223     }
    224 
    225     protected override bool[] Extract(Box box, Type type, Mapper mapper) {
    226       var boolArrayBox = mapper.GetBoolArrayBox(box.BoxId);
    227       return boolArrayBox.Values.ToArray();
    228     }
     203    protected override void Populate(Box box, bool[] value, Mapper mapper) { box.Bools.AddRange(value); }
     204    protected override bool[] Extract(Box box, Type type, Mapper mapper) { return box.Bools.ToArray(); }
    229205  }
    230206
     
    232208  [StorableType("6548E9F0-621D-47BA-A605-8A47EF85C231")]
    233209  internal sealed class IntArrayBoxTransformer : BoxTransformer<int[]> {
    234     protected override void Populate(Box box, int[] value, Mapper mapper) {
    235       var intArrayBox = new IntArrayBox();
    236       intArrayBox.Values.AddRange(value);
    237       box.BoxId = mapper.GetIntArrayBoxId(intArrayBox);
    238     }
    239 
    240     protected override int[] Extract(Box box, Type type, Mapper mapper) {
    241       var intArrayBox = mapper.GetIntArrayBox(box.BoxId);
    242       return intArrayBox.Values.ToArray();
    243     }
     210    protected override void Populate(Box box, int[] value, Mapper mapper) { box.Ints.AddRange(value); }
     211    protected override int[] Extract(Box box, Type type, Mapper mapper) { return box.Ints.ToArray(); }
    244212  }
    245213
     
    247215  [StorableType("4127B466-AFC0-4050-8C45-1376A0E3E016")]
    248216  internal sealed class UnsignedIntArrayBoxTransformer : BoxTransformer<uint[]> {
    249     protected override void Populate(Box box, uint[] value, Mapper mapper) {
    250       var unsignedIntArrayBox = new UnsignedIntArrayBox();
    251       unsignedIntArrayBox.Values.AddRange(value);
    252       box.BoxId = mapper.GetUnsignedIntArrayBoxId(unsignedIntArrayBox);
    253     }
    254 
    255     protected override uint[] Extract(Box box, Type type, Mapper mapper) {
    256       var unsignedIntArrayBox = mapper.GetUnsignedIntArrayBox(box.BoxId);
    257       return unsignedIntArrayBox.Values.ToArray();
    258     }
     217    protected override void Populate(Box box, uint[] value, Mapper mapper) { box.UInts.AddRange(value); }
     218    protected override uint[] Extract(Box box, Type type, Mapper mapper) { return box.UInts.ToArray(); }
    259219  }
    260220
     
    262222  [StorableType("C2ED50C8-C340-40C1-B00C-2F398EB709A0")]
    263223  internal sealed class LongArrayBoxTransformer : BoxTransformer<long[]> {
    264     protected override void Populate(Box box, long[] value, Mapper mapper) {
    265       var longArrayBox = new LongArrayBox();
    266       longArrayBox.Values.AddRange(value);
    267       box.BoxId = mapper.GetLongArrayBoxId(longArrayBox);
    268     }
    269 
    270     protected override long[] Extract(Box box, Type type, Mapper mapper) {
    271       var longArrayBox = mapper.GetLongArrayBox(box.BoxId);
    272       return longArrayBox.Values.ToArray();
    273     }
     224    protected override void Populate(Box box, long[] value, Mapper mapper) { box.Longs.AddRange(value); }
     225    protected override long[] Extract(Box box, Type type, Mapper mapper) { return box.Longs.ToArray(); }
    274226  }
    275227
     
    277229  [StorableType("641AE353-5373-4811-BACB-C13D3144809C")]
    278230  internal sealed class UnsignedLongArrayBoxTransformer : BoxTransformer<ulong[]> {
    279     protected override void Populate(Box box, ulong[] value, Mapper mapper) {
    280       var unsignedLongArrayBox = new UnsignedLongArrayBox();
    281       unsignedLongArrayBox.Values.AddRange(value);
    282       box.BoxId = mapper.GetUnsignedLongArrayBoxId(unsignedLongArrayBox);
    283     }
    284 
    285     protected override ulong[] Extract(Box box, Type type, Mapper mapper) {
    286       var unsignedLongArrayBox = mapper.GetUnsignedLongArrayBox(box.BoxId);
    287       return unsignedLongArrayBox.Values.ToArray();
    288     }
     231    protected override void Populate(Box box, ulong[] value, Mapper mapper) { box.ULongs.AddRange(value); }
     232    protected override ulong[] Extract(Box box, Type type, Mapper mapper) { return box.ULongs.ToArray(); }
    289233  }
    290234
     
    292236  [StorableType("AEE9384F-3857-4CE4-AE30-B99474F7A6C9")]
    293237  internal sealed class FloatArrayBoxTransformer : BoxTransformer<float[]> {
    294     protected override void Populate(Box box, float[] value, Mapper mapper) {
    295       var floatArrayBox = new FloatArrayBox();
    296       floatArrayBox.Values.AddRange(value);
    297       box.BoxId = mapper.GetFloatArrayBoxId(floatArrayBox);
    298     }
    299 
    300     protected override float[] Extract(Box box, Type type, Mapper mapper) {
    301       var floatArrayBox = mapper.GetFloatArrayBox(box.BoxId);
    302       return floatArrayBox.Values.ToArray();
    303     }
     238    protected override void Populate(Box box, float[] value, Mapper mapper) { box.Floats.AddRange(value); }
     239    protected override float[] Extract(Box box, Type type, Mapper mapper) { return box.Floats.ToArray(); }
    304240  }
    305241
     
    307243  [StorableType("17D0BA74-CB84-405C-8DBB-D9E361274A0A")]
    308244  internal sealed class DoubleArrayBoxTransformer : BoxTransformer<double[]> {
    309     protected override void Populate(Box box, double[] value, Mapper mapper) {
    310       var doubleArrayBox = new DoubleArrayBox();
    311       doubleArrayBox.Values.AddRange(value);
    312       box.BoxId = mapper.GetDoubleArrayBoxId(doubleArrayBox);
    313     }
    314 
    315     protected override double[] Extract(Box box, Type type, Mapper mapper) {
    316       var doubleArrayBox = mapper.GetDoubleArrayBox(box.BoxId);
    317       return doubleArrayBox.Values.ToArray();
    318     }
     245    protected override void Populate(Box box, double[] value, Mapper mapper) { box.Doubles.AddRange(value); }
     246    protected override double[] Extract(Box box, Type type, Mapper mapper) { return box.Doubles.ToArray(); }
    319247  }
    320248
     
    322250  [StorableType("A076D11E-89AA-43C8-87F5-A0D0F52569EB")]
    323251  internal sealed class ByteArrayBoxTransformer : BoxTransformer<byte[]> {
    324     protected override void Populate(Box box, byte[] value, Mapper mapper) {
    325       box.Bytes = ByteString.CopyFrom(value);
    326     }
    327 
    328     protected override byte[] Extract(Box box, Type type, Mapper mapper) {
    329       return box.Bytes.ToArray();
    330     }
     252    protected override void Populate(Box box, byte[] value, Mapper mapper) { box.Bytes = ByteString.CopyFrom(value); }
     253    protected override byte[] Extract(Box box, Type type, Mapper mapper) { return box.Bytes.ToArray(); }
    331254  }
    332255
     
    334257  [StorableType("74F6FD4B-D7D7-43CD-B28B-3A775505FEE3")]
    335258  internal sealed class SByteArrayBoxTransformer : BoxTransformer<sbyte[]> {
    336     protected override void Populate(Box box, sbyte[] value, Mapper mapper) {
    337       box.Bytes = ByteString.CopyFrom(value.Select(x => (byte)x).ToArray());
    338     }
    339 
    340     protected override sbyte[] Extract(Box box, Type type, Mapper mapper) {
    341       return box.Bytes.Select(x => (sbyte)x).ToArray();
    342     }
     259    protected override void Populate(Box box, sbyte[] value, Mapper mapper) { box.Bytes = ByteString.CopyFrom(value.Select(x => (byte)x).ToArray()); }
     260    protected override sbyte[] Extract(Box box, Type type, Mapper mapper) { return box.Bytes.Select(x => (sbyte)x).ToArray(); }
    343261  }
    344262
     
    420338      var rank = array.Rank;
    421339
    422       var uIntArrayBox = new UnsignedIntArrayBox();
    423       uIntArrayBox.Values.Add(mapper.GetBoxId(rank));
     340      var uints = box.UInts;
     341      uints.Add((uint)rank);
    424342
    425343      int[] lengths = new int[rank];
    426344      int[] lowerBounds = new int[rank];
    427345      for (int i = 0; i < rank; i++) {
    428         lengths[i] = array.GetLength(i);
    429         lowerBounds[i] = array.GetLowerBound(i);
    430       }
    431 
    432       uIntArrayBox.Values.AddRange(lengths.Select(x => mapper.GetBoxId(x)));
    433       uIntArrayBox.Values.AddRange(lowerBounds.Select(x => mapper.GetBoxId(x)));
     346        uints.Add(mapper.GetBoxId(lengths[i] = array.GetLength(i)));
     347        uints.Add(mapper.GetBoxId(lowerBounds[i] = array.GetLowerBound(i)));
     348      }
    434349
    435350      int[] positions = (int[])lowerBounds.Clone();
    436351      while (positions[rank - 1] < lengths[rank - 1] + lowerBounds[rank - 1]) {
    437         uIntArrayBox.Values.Add(mapper.GetBoxId(array.GetValue(positions)));
     352        uints.Add(mapper.GetBoxId(array.GetValue(positions)));
    438353        positions[0] += 1;
    439354        for (int i = 0; i < rank - 1; i++) {
     
    446361        }
    447362      }
    448 
    449       box.BoxId = mapper.GetUnsignedIntArrayBoxId(uIntArrayBox);
    450363    }
    451364
    452365    protected override object Extract(Box box, Type type, Mapper mapper) {
    453       var uIntArrayBox = mapper.GetUnsignedIntArrayBox(box.BoxId);
    454       var rank = (int)mapper.GetObject(uIntArrayBox.Values[0]);
     366      var uints = box.UInts;
     367      var rank = (int)uints[0];
    455368
    456369      int[] lengths = new int[rank], lowerBounds = new int[rank];
    457       for (int i = 0; i < rank; i++)
    458         lengths[i] = (int)mapper.GetObject(uIntArrayBox.Values[i + 1]);
    459       for (int i = 0; i < rank; i++)
    460         lowerBounds[i] = (int)mapper.GetObject(uIntArrayBox.Values[i + 1 + rank]);
     370      for (int i = 0; i < rank; i++) {
     371        lengths[i] = (int)mapper.GetObject(uints[2 * i + 1]);
     372        lowerBounds[i] = (int)mapper.GetObject(uints[2 * i + 2]);
     373      }
    461374
    462375      return Array.CreateInstance(type.GetElementType(), lengths, lowerBounds);
     
    465378    public override void FillFromBox(object obj, Box box, Mapper mapper) {
    466379      var array = (Array)obj;
    467       var uIntArrayBox = mapper.GetUnsignedIntArrayBox(box.BoxId);
    468       var rank = (int)mapper.GetObject(uIntArrayBox.Values[0]);
     380      var uints = box.UInts;
     381      var rank = (int)uints[0];
    469382
    470383      int[] lengths = new int[rank], lowerBounds = new int[rank];
    471       for (int i = 0; i < rank; i++)
    472         lengths[i] = (int)mapper.GetObject(uIntArrayBox.Values[i + 1]);
    473       for (int i = 0; i < rank; i++)
    474         lowerBounds[i] = (int)mapper.GetObject(uIntArrayBox.Values[i + 1 + rank]);
     384      for (int i = 0; i < rank; i++) {
     385        lengths[i] = (int)mapper.GetObject(uints[2 * i + 1]);
     386        lowerBounds[i] = (int)mapper.GetObject(uints[2 * i + 2]);
     387      }
    475388
    476389      int[] positions = (int[])lowerBounds.Clone();
    477       var e = uIntArrayBox.Values.Skip(1 + 2 * rank).GetEnumerator();
     390      var e = uints.Skip(1 + 2 * rank).GetEnumerator();
    478391      while (e.MoveNext()) {
    479392        int[] currentPositions = positions;
     
    507420
    508421    protected override void Populate(Box box, object value, Mapper mapper) {
    509       var uIntArrayBox = new UnsignedIntArrayBox();
     422      var uints = box.UInts;
    510423
    511424      var type = value.GetType();
    512425      var propertyInfo = type.GetProperty("Comparer");
    513426      if (propertyInfo != null) {
    514         // TODO: where to store id for comparer box? (atm: first element in int array ...)
    515427        var comparer = propertyInfo.GetValue(value);
    516428        var comparerType = comparer.GetType();
    517429        if (StorableTypeAttribute.IsStorableType(comparerType))
    518           uIntArrayBox.Values.Add(mapper.GetBoxId(comparer));
     430          box.ComparerId = mapper.GetBoxId(comparer);
    519431        else if (comparerType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy).Any())
    520432          throw new NotSupportedException("Cannot serialize non-storable equality comparers with fields");
    521433        else
    522           uIntArrayBox.Values.Add(mapper.GetBoxId(comparerType));
     434          box.ComparerId = mapper.GetBoxId(comparerType);
    523435      }
    524436
    525437      foreach (var item in (IEnumerable)value)
    526         uIntArrayBox.Values.Add(mapper.GetBoxId(item));
    527 
    528       box.BoxId = mapper.GetUnsignedIntArrayBoxId(uIntArrayBox);
     438        uints.Add(mapper.GetBoxId(item));
    529439    }
    530440
     
    534444
    535445    public override void FillFromBox(object obj, Box box, Mapper mapper) {
    536       var uIntArrayBox = mapper.GetUnsignedIntArrayBox(box.BoxId);
    537       var elements = uIntArrayBox.Values.Select(mapper.GetObject);
     446      var uints = box.UInts;
     447      var elements = uints.Select(mapper.GetObject);
    538448      var type = obj.GetType();
    539449
     
    548458        if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(HashSet<>)) {
    549459          var fieldInfo = type.GetField("m_comparer", BindingFlags.NonPublic | BindingFlags.Instance);
    550           var comparerObj = mapper.GetObject(uIntArrayBox.Values[0]);
     460          var comparerObj = mapper.GetObject(box.ComparerId);
    551461          var comparer = comparerObj is Type ? Activator.CreateInstance((Type)comparerObj) : comparerObj;
    552462          fieldInfo.SetValue(obj, comparer);
    553           elements = elements.Skip(1);
    554463        }
    555464      }
     
    569478
    570479    protected override void Populate(Box box, object value, Mapper mapper) {
    571       var dictionaryBox = new DictionaryBox();
    572       foreach (DictionaryEntry item in (IDictionary)value) {
    573         dictionaryBox.KeyValuePairs.Add(mapper.GetBoxId(item.Key), mapper.GetBoxId(item.Value));
    574       }
     480      var kvps = box.KeyValuePairs;
     481      foreach (DictionaryEntry item in (IDictionary)value)
     482        kvps.Add(mapper.GetBoxId(item.Key), mapper.GetBoxId(item.Value));
    575483
    576484      var type = value.GetType();
     
    580488      var comparerType = comparer.GetType();
    581489      if (StorableTypeAttribute.IsStorableType(comparerType))
    582         dictionaryBox.ComparerId = mapper.GetBoxId(comparer);
     490        box.ComparerId = mapper.GetBoxId(comparer);
    583491      else if (comparerType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy).Any())
    584492        throw new NotSupportedException("Cannot serialize non-storable equality comparers with fields");
    585493      else
    586         dictionaryBox.ComparerId = mapper.GetBoxId(comparerType);
    587 
    588       box.BoxId = mapper.GetDictionaryBoxId(dictionaryBox);
     494        box.ComparerId = mapper.GetBoxId(comparerType);
    589495    }
    590496
    591497    protected override object Extract(Box box, Type type, Mapper mapper) {
    592       var dictionaryBox = mapper.GetDictionaryBox(box.BoxId);
    593       return Activator.CreateInstance(type, dictionaryBox.KeyValuePairs.Count);
     498      return Activator.CreateInstance(type, box.KeyValuePairs.Count);
    594499    }
    595500
    596501    public override void FillFromBox(object obj, Box box, Mapper mapper) {
    597502      var type = obj.GetType();
    598       var dictionaryBox = mapper.GetDictionaryBox(box.BoxId);
    599       var comparerObj = mapper.GetObject(dictionaryBox.ComparerId);
     503      var comparerObj = mapper.GetObject(box.ComparerId);
    600504      var comparer = comparerObj is Type ? Activator.CreateInstance((Type)comparerObj) : comparerObj;
    601505
     
    604508
    605509      var addMethod = type.GetMethod("Add");
    606       foreach (var entry in dictionaryBox.KeyValuePairs) {
     510      var kvps = box.KeyValuePairs;
     511      foreach (var entry in kvps) {
    607512        var key = mapper.GetObject(entry.Key);
    608513        var value = mapper.GetObject(entry.Value);
     
    670575  [StorableType("9D99D155-E3BB-40CE-AF64-6E153D876148")]
    671576  internal sealed class DateTimeBoxTransformer : BoxTransformer<DateTime> {
    672     protected override void Populate(Box box, DateTime value, Mapper mapper) {
    673       box.Long = value.Ticks;
    674     }
    675 
    676     protected override DateTime Extract(Box box, Type type, Mapper mapper) {
    677       return new DateTime(box.Long);
    678     }
     577    protected override void Populate(Box box, DateTime value, Mapper mapper) { box.Long = value.Ticks; }
     578    protected override DateTime Extract(Box box, Type type, Mapper mapper) { return new DateTime(box.Long); }
    679579  }
    680580
     
    682582  [StorableType("9CA7C1F7-784C-48D5-A6F4-E1FD7B3A2FEC")]
    683583  internal sealed class TimeSpanBoxTransformer : BoxTransformer<TimeSpan> {
    684     protected override void Populate(Box box, TimeSpan value, Mapper mapper) {
    685       box.Long = value.Ticks;
    686     }
    687 
    688     protected override TimeSpan Extract(Box box, Type type, Mapper mapper) {
    689       return new TimeSpan(box.Long);
    690     }
     584    protected override void Populate(Box box, TimeSpan value, Mapper mapper) { box.Long = value.Ticks; }
     585    protected override TimeSpan Extract(Box box, Type type, Mapper mapper) { return new TimeSpan(box.Long); }
    691586  }
    692587
     
    695590  internal sealed class PointTransformer : BoxTransformer<Point> {
    696591    protected override void Populate(Box box, Point value, Mapper mapper) {
    697       var intArrayBox = new IntArrayBox();
    698       intArrayBox.Values.AddRange(new[] { value.X, value.Y });
    699       box.BoxId = mapper.GetIntArrayBoxId(intArrayBox);
     592      box.Ints.AddRange(new[] { value.X, value.Y });
    700593    }
    701594
    702595    protected override Point Extract(Box box, Type type, Mapper mapper) {
    703       var intArrayBox = mapper.GetIntArrayBox(box.BoxId);
    704       return new Point(intArrayBox.Values[0], intArrayBox.Values[1]);
     596      var ints = box.Ints;
     597      return new Point(ints[0], ints[1]);
    705598    }
    706599  }
     
    730623  internal sealed class FontTransformer : BoxTransformer<Font> {
    731624    protected override void Populate(Box box, Font value, Mapper mapper) {
    732       var unsignedIntArrayBox = new UnsignedIntArrayBox();
    733       unsignedIntArrayBox.Values.Add(mapper.GetStringId(GetFontFamilyName(value.FontFamily)));
    734       unsignedIntArrayBox.Values.Add(mapper.GetBoxId(value.Size));
    735       unsignedIntArrayBox.Values.Add(mapper.GetBoxId(value.Style));
    736       unsignedIntArrayBox.Values.Add(mapper.GetBoxId(value.Unit));
    737       unsignedIntArrayBox.Values.Add(mapper.GetBoxId(value.GdiCharSet));
    738       unsignedIntArrayBox.Values.Add(mapper.GetBoxId(value.GdiVerticalFont));
    739       box.BoxId = mapper.GetUnsignedIntArrayBoxId(unsignedIntArrayBox);
     625      var uints = box.UInts;
     626      uints.Add(mapper.GetStringId(GetFontFamilyName(value.FontFamily)));
     627      uints.Add(mapper.GetBoxId(value.Size));
     628      uints.Add(mapper.GetBoxId(value.Style));
     629      uints.Add(mapper.GetBoxId(value.Unit));
     630      uints.Add(mapper.GetBoxId(value.GdiCharSet));
     631      uints.Add(mapper.GetBoxId(value.GdiVerticalFont));
    740632    }
    741633
    742634    protected override Font Extract(Box box, Type type, Mapper mapper) {
    743       var value = mapper.GetUnsignedIntArrayBox(box.BoxId);
    744       var fontData = value.Values;
     635      var fontData = box.UInts;
    745636      return new Font(
    746637        GetFontFamily(mapper.GetString(fontData[0])),
     
    780671
    781672    protected override void Populate(Box box, object value, Mapper mapper) {
    782       var unsignedIntArrayBox = new UnsignedIntArrayBox();
     673      var uints = box.UInts;
     674
    783675      var type = value.GetType();
    784       var pair = new uint[2];
    785       pair[0] = mapper.GetBoxId(type.GetProperty("Key").GetValue(value));
    786       pair[1] = mapper.GetBoxId(type.GetProperty("Value").GetValue(value));
    787       unsignedIntArrayBox.Values.AddRange(pair);
    788       box.BoxId = mapper.GetUnsignedIntArrayBoxId(unsignedIntArrayBox);
     676      var pair = new[] {
     677        mapper.GetBoxId(type.GetProperty("Key").GetValue(value)) ,
     678        mapper.GetBoxId(type.GetProperty("Value").GetValue(value))
     679      };
     680
     681      uints.AddRange(pair);
    789682    }
    790683
    791684    public override void FillFromBox(object obj, Box box, Mapper mapper) {
    792       var b = mapper.GetUnsignedIntArrayBox(box.BoxId);
    793       var key = mapper.GetObject(b.Values[0]);
    794       var val = mapper.GetObject(b.Values[1]);
     685      var uints = box.UInts;
     686      var key = mapper.GetObject(uints[0]);
     687      var val = mapper.GetObject(uints[1]);
    795688      var type = obj.GetType();
    796689      //DataMemberAccessor.GenerateFieldSetter(type.GetField("key", BindingFlags.NonPublic | BindingFlags.Instance))(obj, key);
     
    819712    protected override void Populate(Box box, object value, Mapper mapper) {
    820713      var type = value.GetType();
    821       var uIntArrayBox = new UnsignedIntArrayBox();
     714      var uints = box.UInts;
    822715      for (int i = 1; i <= type.GetGenericArguments().Length; i++) {
    823716        string name = string.Format("Item{0}", i);
    824         uIntArrayBox.Values.Add(mapper.GetBoxId(type.GetProperty(name).GetValue(value)));
    825       }
    826       box.BoxId = mapper.GetUnsignedIntArrayBoxId(uIntArrayBox);
     717        uints.Add(mapper.GetBoxId(type.GetProperty(name).GetValue(value)));
     718      }
    827719    }
    828720
     
    835727
    836728    public override void FillFromBox(object obj, Box box, Mapper mapper) {
    837       var uIntArrayBox = mapper.GetUnsignedIntArrayBox(box.BoxId);
    838       var elements = uIntArrayBox.Values.Select(mapper.GetObject).ToArray();
     729      var uints = box.UInts;
     730      var elements = uints.Select(mapper.GetObject).ToArray();
    839731      var type = obj.GetType();
    840732      for (int i = 1; i <= elements.Length; i++) {
     
    853745
    854746    protected override void Populate(Box box, object value, Mapper mapper) {
    855       var b = new StorableClassBox();
    856747      var type = value.GetType();
    857748
    858       var components = new Dictionary<uint, uint>();
    859       foreach (var fieldInfo in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) {
    860         var component = mapper.GetBoxId(fieldInfo.GetValue(value));
    861         components.Add(mapper.GetStringId(fieldInfo.Name), component);
    862       }
    863 
    864       foreach (var component in components) {
    865         b.KeyValuePairs.Add(component.Key, component.Value);
    866       }
    867 
    868       box.BoxId = mapper.GetStorableClassBoxId(b);
     749      var kvps = box.KeyValuePairs;
     750      foreach (var fieldInfo in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
     751        kvps.Add(mapper.GetStringId(fieldInfo.Name), mapper.GetBoxId(fieldInfo.GetValue(value)));
    869752    }
    870753
    871754    protected override object Extract(Box box, Type type, Mapper mapper) {
    872       var data = mapper.GetStorableClassBox(box.BoxId);
    873755      var obj = Activator.CreateInstance(type);
    874756
    875       var components = new Dictionary<uint, uint>();
    876       foreach (var kvp in data.KeyValuePairs) {
    877         components.Add(kvp.Key, kvp.Value);
    878       }
    879 
    880       foreach (var t in components) {
     757      var kvps = box.KeyValuePairs;
     758      foreach (var t in kvps) {
    881759        string name = mapper.GetString(t.Key);
    882760        MemberInfo[] mis = type.GetMember(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
     
    894772      return obj;
    895773    }
    896 
    897774  }
    898775
     
    906783
    907784    protected override void Populate(Box box, object value, Mapper mapper) {
    908       var b = new StorableClassBox();
    909       var type = value.GetType();
    910       var typeInfo = Mapper.StaticCache.GetTypeInfo(type);
    911 
     785      var kvps = box.KeyValuePairs;
     786      var parentTypeVersions = box.UInts;
    912787      var emptyArgs = new object[0];
    913       foreach (var hook in typeInfo.BeforeSerializationHooks) {
    914         hook.Invoke(value, emptyArgs);
    915       }
    916 
    917       var components = new Dictionary<uint, uint>();
    918       foreach (var componentInfo in typeInfo.Fields) {
    919         var field = (FieldInfo)componentInfo.MemberInfo;
    920         var component = mapper.GetBoxId(field.GetValue(value));
    921         components.Add(mapper.GetStringId(componentInfo.Name), component);
    922       }
    923 
    924       foreach (var componentInfo in typeInfo.Properties.Where(x => x.Readable)) {
    925         var property = (PropertyInfo)componentInfo.MemberInfo;
    926         var component = mapper.GetBoxId(property.GetValue(value, null));
    927         components.Add(mapper.GetStringId(componentInfo.Name), component);
    928       }
    929 
    930       foreach (var component in components) {
    931         b.KeyValuePairs.Add(component.Key, component.Value);
    932       }
    933 
    934       box.BoxId = mapper.GetStorableClassBoxId(b);
     788
     789      var originalType = value.GetType();
     790
     791      // traverse type hierarchy
     792      var type = originalType;
     793      while (StorableTypeAttribute.IsStorableType(type)) {
     794        var typeInfo = Mapper.StaticCache.GetTypeInfo(type);
     795        var attribute = typeInfo.StorableTypeAttribute;
     796        var guid = typeInfo.StorableTypeAttribute.Guid;
     797
     798        foreach (var hook in typeInfo.BeforeSerializationHooks)
     799          hook.Invoke(value, emptyArgs);
     800
     801        foreach (var componentInfo in typeInfo.Fields) {
     802          var field = (FieldInfo)componentInfo.MemberInfo;
     803          kvps.Add(
     804            mapper.GetStringId(componentInfo.FullName),
     805            mapper.GetBoxId(field.GetValue(value))
     806          );
     807        }
     808
     809        foreach (var componentInfo in typeInfo.Properties.Where(x => x.Readable)) {
     810          var property = (PropertyInfo)componentInfo.MemberInfo;
     811          kvps.Add(
     812            mapper.GetStringId(componentInfo.FullName),
     813            mapper.GetBoxId(property.GetValue(value, null))
     814          );
     815        }
     816
     817        if (type != originalType) {
     818          parentTypeVersions.AddRange(new[] { mapper.GetStringId(guid.ToString()), attribute.Version });
     819        }
     820
     821        type = type.BaseType;
     822      }
    935823    }
    936824
     
    940828
    941829    public override void FillFromBox(object obj, Box box, Mapper mapper) {
    942       var data = mapper.GetStorableClassBox(box.BoxId);
    943       var type = obj.GetType();
     830      var kvps = box.KeyValuePairs;
     831      var parentTypeVersions = box.UInts;
     832      var emptyArgs = new object[0];
     833
     834      var dict = new Dictionary<string, object>();
     835      foreach (var entry in kvps) {
     836        string key = mapper.GetString(entry.Key);
     837        object value = mapper.GetObject(entry.Value);
     838        dict.Add(key, value);
     839      }
     840
     841      var type = (Type)mapper.GetObject(box.TypeBoxId);
     842      var typeBox = mapper.GetBox(box.TypeBoxId);
    944843      var typeInfo = Mapper.StaticCache.GetTypeInfo(type);
    945       var typeBox = mapper.GetTypeBox(mapper.GetBox(box.TypeId).BoxId);
    946       var version = Math.Max(typeBox.Version, 1);
    947       var typeGuid = typeInfo.StorableTypeAttribute.Guid;
    948 
    949       var components = new Dictionary<uint, uint>();
    950       foreach (var kvp in data.KeyValuePairs) {
    951         components.Add(kvp.Key, kvp.Value);
    952       }
    953 
    954       var conversionMethods =
    955         type.Assembly.GetTypes().SelectMany(t =>
    956           t.GetMethods(BindingFlags.NonPublic | BindingFlags.Static)
    957           .Where(StorableConversionAttribute.IsStorableConversionMethod)
    958           .Where(mi => StorableConversionAttribute.GetGuid(mi) == typeGuid &&
    959                        StorableConversionAttribute.GetVersion(mi) >= version))
    960           .OrderBy(StorableConversionAttribute.GetVersion)
    961           .ToArray();
    962 
    963       // put all objects into dictionary for conversion
    964       var dict = new Dictionary<string, object>();
    965       foreach (var component in components) {
    966         dict.Add(mapper.GetString(component.Key), mapper.GetObject(component.Value));
    967       }
    968 
    969       Dictionary<string, object> lastDict = new Dictionary<string, object>();
    970       foreach (var convMeth in conversionMethods) {
    971         if (StorableConversionAttribute.GetVersion(convMeth) != version)
    972           throw new PersistenceException(string.Format("No conversion method defined for type {0} version {1}", typeGuid, version));
    973         lastDict = (Dictionary<string, object>)convMeth.Invoke(null, new object[] { dict });
    974         foreach (var kvp in lastDict) {
    975           dict[kvp.Key] = kvp.Value;
    976         }
    977         version++;
    978       }
    979       if (version != typeInfo.StorableTypeAttribute.Version)
    980         throw new PersistenceException(string.Format("Missing one or more conversion methods for type {0} version {1}",
    981           typeGuid, typeInfo.StorableTypeAttribute.Version));
    982 
    983       // set default values for all fields and properties
    984       foreach (var componentInfo in typeInfo.Fields) {
    985         var field = (FieldInfo)componentInfo.MemberInfo;
    986         if (componentInfo.StorableAttribute != null && componentInfo.StorableAttribute.DefaultValue != null)
    987           field.SetValue(obj, componentInfo.StorableAttribute.DefaultValue);
    988       }
    989       foreach (var componentInfo in typeInfo.Properties.Where(x => x.Writeable)) {
    990         var property = (PropertyInfo)componentInfo.MemberInfo;
    991         if (componentInfo.StorableAttribute != null && componentInfo.StorableAttribute.DefaultValue != null)
    992           property.SetValue(obj, componentInfo.StorableAttribute.DefaultValue, null);
    993       }
    994 
    995       // set all members as generated by conversion method chain
    996       foreach (var kvp in dict) {
    997         var key = kvp.Key;
    998         var val = kvp.Value;
    999         var fieldInfo = typeInfo.Fields.FirstOrDefault(fi => fi.Name == key);
    1000         if (fieldInfo != null) {
    1001           var field = (FieldInfo)fieldInfo.MemberInfo;
    1002           field.SetValue(obj, val);
    1003           lastDict.Remove(fieldInfo.Name); // only for consistency check
    1004           continue;
    1005         }
    1006         var propInfo = typeInfo.Properties.Where(x => x.Writeable).FirstOrDefault(pi => pi.Name == key);
    1007         if (propInfo != null) {
    1008           var prop = (PropertyInfo)propInfo.MemberInfo;
    1009           prop.SetValue(obj, val, null);
    1010           lastDict.Remove(propInfo.Name);    // only for consistency check
    1011           continue;
    1012         }
    1013       }
    1014 
    1015       if (lastDict.Any())
    1016         throw new PersistenceException(string.Format("Invalid conversion method. The following members are undefined in type {0} version {1}: {2}",
    1017           typeGuid, typeInfo.StorableTypeAttribute.Version,
    1018           string.Join(", ", lastDict.Keys)));
    1019 
    1020       var emptyArgs = new object[0];
    1021       foreach (var hook in typeInfo.AfterDeserializationHooks) {
    1022         hook.Invoke(obj, emptyArgs);
     844
     845      var typeVersions = new List<Tuple<Guid, uint>>();
     846      typeVersions.Add(Tuple.Create(typeInfo.StorableTypeAttribute.Guid, typeBox.TypeVersion));
     847      for (int i = 0; i < parentTypeVersions.Count; i += 2)
     848        typeVersions.Add(Tuple.Create(Guid.Parse(mapper.GetString(parentTypeVersions[i])), parentTypeVersions[i + 1]));
     849
     850      var originalType = type;
     851      var originalTypeInfo = typeInfo;
     852
     853      foreach (var entry in typeVersions) {
     854        var guid = entry.Item1;
     855        var version = entry.Item2;
     856
     857        var conversionMethods = (from methodInfo in Mapper.StaticCache.GetStorableConversions(guid)
     858                                 let attrib = StorableConversionAttribute.GetStorableConversionAttribute(methodInfo)
     859                                 where attrib.Version >= version
     860                                 orderby attrib.Version
     861                                 select methodInfo).ToList();
     862
     863        uint targetVersion;
     864
     865        try {
     866          type = Mapper.StaticCache.GetType(guid);
     867          typeInfo = Mapper.StaticCache.GetTypeInfo(type);
     868          targetVersion = typeInfo.StorableTypeAttribute.Version;
     869        } catch (KeyNotFoundException) {
     870          targetVersion = 0;
     871        }
     872
     873        Dictionary<string, object> lastDict = new Dictionary<string, object>();
     874        foreach (var conversionMethod in conversionMethods) {
     875          if (StorableConversionAttribute.GetVersion(conversionMethod) != version)
     876            throw new PersistenceException(string.Format("No conversion method defined for type {0} version {1}", guid, version));
     877
     878          lastDict = (Dictionary<string, object>)conversionMethod.Invoke(null, new object[] { dict });
     879          foreach (var kvp in lastDict) dict[kvp.Key] = kvp.Value;
     880
     881          version++;
     882        }
     883
     884        if (version < targetVersion)
     885          throw new PersistenceException(string.Format("Missing one or more conversion methods for type {0} version {1}", guid, version));
     886      }
     887
     888      var typeStack = new Stack<Tuple<Type, TypeInfo>>();
     889      type = originalType;
     890      typeInfo = originalTypeInfo;
     891
     892      while (StorableTypeAttribute.IsStorableType(type)) {
     893        typeInfo = Mapper.StaticCache.GetTypeInfo(type);
     894        typeStack.Push(Tuple.Create(type, typeInfo));
     895        type = type.BaseType;
     896      }
     897
     898      foreach (var frame in typeStack) {
     899        type = frame.Item1;
     900        typeInfo = frame.Item2;
     901
     902        // set default values for all fields and properties
     903        foreach (var componentInfo in typeInfo.Fields) {
     904          var attrib = componentInfo.StorableAttribute;
     905          var fieldInfo = (FieldInfo)componentInfo.MemberInfo;
     906          if (attrib != null && attrib.DefaultValue != null)
     907            fieldInfo.SetValue(obj, attrib.DefaultValue);
     908        }
     909        foreach (var componentInfo in typeInfo.Properties.Where(x => x.Writeable)) {
     910          var attrib = componentInfo.StorableAttribute;
     911          var property = (PropertyInfo)componentInfo.MemberInfo;
     912          if (attrib != null && attrib.DefaultValue != null)
     913            property.SetValue(obj, attrib.DefaultValue, null);
     914        }
     915
     916        // set all members as generated by conversion method chain
     917        foreach (var kvp in dict) {
     918          string key = kvp.Key;
     919          object val = kvp.Value;
     920
     921          string[] keyParts = key.Split('.');
     922          var guid = Guid.Parse(keyParts[0]);
     923          string ident = keyParts[1];
     924
     925          if (guid != typeInfo.StorableTypeAttribute.Guid) continue;
     926
     927          var fieldInfo = typeInfo.Fields.FirstOrDefault(fi => fi.Name == ident);
     928          if (fieldInfo != null) {
     929            var field = (FieldInfo)fieldInfo.MemberInfo;
     930            field.SetValue(obj, val);
     931            //dict.Remove(guid.ToString().ToUpperInvariant() + "." + fieldInfo.Name); // only for consistency check
     932            continue;
     933          }
     934
     935          var propInfo = typeInfo.Properties.Where(x => x.Writeable).FirstOrDefault(fi => fi.Name == ident);
     936          if (propInfo != null) {
     937            var prop = (PropertyInfo)propInfo.MemberInfo;
     938            prop.SetValue(obj, val, null);
     939            //dict.Remove(guid.ToString().ToUpperInvariant() + "." + propInfo.Name); // only for consistency check
     940            continue;
     941          }
     942        }
     943
     944        //var undefinedMembers = dict.Where(x => Guid.Parse(x.Key.Split('.')[0]) == typeInfo.StorableTypeAttribute.Guid);
     945
     946        //if (undefinedMembers.Any())
     947        //  throw new PersistenceException(string.Format("Invalid conversion method. The following members are undefined in type {0} version {1}: {2}",
     948        //    typeInfo.StorableTypeAttribute.Guid,
     949        //    typeInfo.StorableTypeAttribute.Version,
     950        //    string.Join(", ", undefinedMembers.Select(x => x.Key))));
     951
     952        foreach (var hook in typeInfo.AfterDeserializationHooks) {
     953          hook.Invoke(obj, emptyArgs);
     954        }
    1023955      }
    1024956    }
Note: See TracChangeset for help on using the changeset viewer.