Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
09/12/11 10:12:50 (13 years ago)
Author:
epitzer
Message:

#1530 Split type and serializer tokens and include special handling for CachedTypeSerializer (this should also fix #1527)

Location:
branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Core
Files:
4 added
1 deleted
4 edited

Legend:

Unmodified
Added
Removed
  • branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Core/DeSerializer.cs

    r5445 r6737  
    3232  /// instantiates objects and fills in values.
    3333  /// </summary>
    34   public class Deserializer {
     34  public sealed class Deserializer {
    3535
    3636    /// <summary>
     
    4040    private class Midwife {
    4141
     42      public string Name { get; private set; }
    4243      public int? Id { get; private set; }
    4344      public bool MetaMode { get; set; }
     
    5354      }
    5455
    55       public Midwife(Type type, ICompositeSerializer compositeSerializer, int? id) {
     56      public Midwife(Type type, ICompositeSerializer compositeSerializer, int? id, string name) {
    5657        this.type = type;
    5758        this.compositeSerializer = compositeSerializer;
    5859        this.Id = id;
     60        this.Name = name;
    5961        MetaMode = false;
    6062        metaInfo = new List<Tag>();
     
    8284
    8385    private readonly Dictionary<int, object> id2obj;
    84     private readonly Dictionary<Type, object> serializerMapping;
    8586    private readonly Stack<Midwife> parentStack;
    86     private readonly Dictionary<int, Type> typeIds;
    87     private Dictionary<Type, object> serializerInstances;
     87    private ReverseTypeCache typeCache;
    8888
    8989    /// <summary>
     
    9393    /// </summary>
    9494    /// <param name="typeCache">The type cache.</param>
    95     public Deserializer(
    96       IEnumerable<TypeMapping> typeCache) {
     95    public Deserializer(ReverseTypeCache typeCache) {
     96      this.typeCache = typeCache;
    9797      id2obj = new Dictionary<int, object>();
    9898      parentStack = new Stack<Midwife>();
    99       typeIds = new Dictionary<int, Type>();
    100       serializerMapping = new Dictionary<Type, object>();
    101       serializerInstances = new Dictionary<Type, object>();
    102       foreach (var typeMapping in typeCache) {
    103         AddTypeInfo(typeMapping);
    104       }
    105     }
    106 
    107     /// <summary>
    108     /// Adds additionaly type information.
    109     /// </summary>
    110     /// <param name="typeMapping">The new type mapping.</param>
    111     public void AddTypeInfo(TypeMapping typeMapping) {
    112       if (typeIds.ContainsKey(typeMapping.Id))
    113         return;
    114       try {
    115         Type type = TypeLoader.Load(typeMapping.TypeName);
    116         typeIds.Add(typeMapping.Id, type);
    117         Type serializerType = TypeLoader.Load(typeMapping.Serializer);
    118         object serializer;
    119         if (serializerInstances.ContainsKey(serializerType)) {
    120           serializer = serializerInstances[serializerType];
    121         } else {
    122           serializer = Activator.CreateInstance(serializerType, true);
    123           serializerInstances.Add(serializerType, serializer);
    124         }
    125         serializerMapping.Add(type, serializer);
    126       } catch (PersistenceException) {
    127         throw;
    128       } catch (Exception e) {
    129         throw new PersistenceException(string.Format(
    130           "Could not add type info for {0} ({1})",
    131           typeMapping.TypeName, typeMapping.Serializer), e);
    132       }
    13399    }
    134100
     
    157123        } else if (t == typeof(TypeToken)) {
    158124          Type((TypeToken)token);
     125        } else if (t == typeof(SerializerToken)) {
     126          Serializer((SerializerToken)token);
    159127        } else {
    160128          throw new PersistenceException("invalid token type");
     
    173141
    174142    private void Type(TypeToken token) {
    175       AddTypeInfo(new TypeMapping(token.Id, token.TypeName, token.Serializer));
     143      typeCache.AddType(token.Id, TypeLoader.Load(token.TypeName));
     144    }
     145
     146    private void Serializer(SerializerToken token) {
     147      typeCache.AddSerializer(token.Id, TypeLoader.Load(token.Serializer));
    176148    }
    177149
    178150    private void CompositeStartHandler(BeginToken token) {
    179151      InstantiateParent();
    180       Type type = typeIds[(int)token.TypeId];
     152      Type type = typeCache.GetType(token.TypeId);
    181153      try {
    182         parentStack.Push(new Midwife(type, (ICompositeSerializer)serializerMapping[type], token.Id));
     154        parentStack.Push(new Midwife(type, typeCache.GetCompositeSerializer(token.TypeId), token.Id, token.Name));
    183155      } catch (Exception e) {
    184156        if (e is InvalidCastException || e is KeyNotFoundException) {
     
    195167
    196168    private void CompositeEndHandler(EndToken token) {
    197       Type type = typeIds[(int)token.TypeId];
    198169      Midwife midwife = parentStack.Pop();
    199170      if (midwife.Obj == null)
    200171        CreateInstance(midwife);
    201172      midwife.Populate();
    202       SetValue(token.Name, midwife.Obj);
     173      SetValue(midwife.Name, midwife.Obj);
    203174    }
    204175
    205176    private void PrimitiveHandler(PrimitiveToken token) {
    206       Type type = typeIds[(int)token.TypeId];
    207177      try {
    208         object value = ((IPrimitiveSerializer)serializerMapping[type]).Parse(token.SerialData);
     178        object value = typeCache.GetPrimitiveSerializer(token.TypeId).Parse(token.SerialData);
    209179        if (token.Id != null)
    210180          id2obj[(int)token.Id] = value;
     
    214184          throw new PersistenceException(String.Format(
    215185            "Invalid primitive serializer configuration for type \"{0}\".",
    216             type.AssemblyQualifiedName), e);
     186            typeCache.GetType(token.TypeId).AssemblyQualifiedName), e);
    217187        } else {
    218188          throw new PersistenceException(String.Format(
    219189            "Unexpected exception while trying to parse object of type \"{0}\".",
    220             type.AssemblyQualifiedName), e);
     190            typeCache.GetType(token.TypeId).AssemblyQualifiedName), e);
    221191        }
    222192      }
  • branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Core/GeneratorBase.cs

    r5445 r6737  
    5757      if (type == typeof(TypeToken))
    5858        return Format((TypeToken)token);
     59      if (type == typeof(SerializerToken))
     60        return Format((SerializerToken)token);
    5961      throw new ApplicationException("Invalid token of type " + type.FullName);
    6062    }
     
    116118    protected abstract T Format(TypeToken typeToken);
    117119
     120    protected abstract T Format(SerializerToken serializerToken);
    118121  }
    119122}
  • branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Core/Serializer.cs

    r6214 r6737  
    2323using System.Collections;
    2424using System.Collections.Generic;
    25 using System.Reflection;
     25using System.Linq;
    2626using System.Text;
    2727using HeuristicLab.Persistence.Auxiliary;
     
    4444  /// and traverses the object graph while the enumerator is iterated
    4545  /// </summary> 
    46   public class Serializer : IEnumerable<ISerializationToken> {
    47 
     46  public sealed class Serializer : IEnumerable<ISerializationToken> {
     47
     48    #region Nested Types
    4849    private class ReferenceEqualityComparer : IEqualityComparer<object> {
    4950
     
    5960
    6061    }
    61 
     62    #endregion
     63
     64    #region Fields
    6265    private readonly object obj;
    6366    private readonly string rootName;
    6467    private readonly Dictionary<object, int> obj2id;
    65     private readonly Dictionary<Type, int> typeCache;
    6668    private readonly Configuration configuration;
    6769    private readonly bool isTestRun;
    6870    private readonly List<Exception> exceptions;
     71    private readonly Stack<string> objectGraphTrace;
     72    private readonly CachedTypeSerializer typeSerializer;
     73    private readonly TypeCache typeCache;
     74    #endregion
    6975
    7076    /// <summary>
     
    8086    public bool InterleaveTypeInformation { get; set; }
    8187
    82     /// <summary>
    83     /// Contains a mapping of type id to type and serializer.
    84     /// </summary>
    85     /// <value>The type cache.</value>
    86     public List<TypeMapping> TypeCache {
    87       get {
    88         BuildTypeCache();
    89         return externalTypeCache;
    90       }
     88    public TypeCache TypeCache {
     89      get { return typeCache; }
    9190    }
    9291
     
    9594    /// necessary to deserialize the object graph again.   
    9695    /// </summary>
    97     public List<string> RequiredFiles {
    98       get {
    99         BuildTypeCache();
    100         return requiredFiles;
    101       }
    102     }
    103 
    104     private List<TypeMapping> externalTypeCache;
    105     private List<string> requiredFiles;
    106     private void BuildTypeCache() {
    107       externalTypeCache = new List<TypeMapping>();
    108       Dictionary<Assembly, bool> assemblies = new Dictionary<Assembly, bool>();
    109       foreach (var pair in typeCache) {
    110         string serializer = null;
    111         IPrimitiveSerializer f = configuration.GetPrimitiveSerializer(pair.Key);
    112         if (f != null) {
    113           serializer = f.GetType().AssemblyQualifiedName;
    114           assemblies[f.GetType().Assembly] = true;
    115         } else {
    116           ICompositeSerializer d = configuration.GetCompositeSerializer(pair.Key);
    117           serializer = d.GetType().AssemblyQualifiedName;
    118           assemblies[d.GetType().Assembly] = true;
    119         }
    120         externalTypeCache.Add(new TypeMapping(pair.Value, pair.Key.AssemblyQualifiedName, serializer));
    121         assemblies[pair.Key.Assembly] = true;
    122       }
    123       Dictionary<string, bool> files = new Dictionary<string, bool>();
    124       foreach (Assembly a in assemblies.Keys) {
    125         files[a.CodeBase] = true;
    126       }
    127       requiredFiles = new List<string>(files.Keys);
    128     }
    129 
    130     public IEnumerable<Type> SerializedTypes {
    131       get {
    132         return typeCache.Keys;
    133       }
    134     }
     96    public IEnumerable<string> GetRequiredFiles() {
     97      HashSet<string> files = new HashSet<string>();
     98      foreach (var t in typeCache.Types) {
     99        files.Add(t.Assembly.CodeBase);
     100        Type serializer = typeCache.GetSerializer(typeCache.GetOrCreateId(t));
     101        if (serializer != null)
     102          files.Add(serializer.Assembly.CodeBase);
     103      }
     104      return files;
     105    }
     106
     107    public IEnumerable<Type> SerializedTypes { get { return typeCache.Types; } }
    135108
    136109    /// <summary>
     
    139112    /// <param name="obj">The object to serialize.</param>
    140113    /// <param name="configuration">The configuration.</param>
    141     public Serializer(object obj, Configuration configuration) :
    142       this(obj, configuration, "ROOT") { }
     114    public Serializer(object obj, Configuration configuration)
     115      : this(obj, configuration, "ROOT") { }
    143116
    144117    /// <summary>
     
    163136      this.obj = obj;
    164137      this.rootName = rootName;
    165       this.configuration = configuration;
    166138      obj2id = new Dictionary<object, int>(new ReferenceEqualityComparer()) { { new object(), 0 } };
    167       typeCache = new Dictionary<Type, int>();
     139      typeCache = new TypeCache();
    168140      this.isTestRun = isTestRun;
    169141      this.exceptions = new List<Exception>();
     142      this.objectGraphTrace = new Stack<string>();
     143      this.typeSerializer = new CachedTypeSerializer(typeCache);
     144      this.configuration = new Configuration(
     145        configuration.Format,
     146        configuration.PrimitiveSerializers,
     147        new[] { typeSerializer }.Concat(configuration.CompositeSerializers));
    170148    }
    171149
     
    206184    }
    207185
    208     private Stack<string> objectGraphTrace = new Stack<string>();
    209186
    210187    private IEnumerator<ISerializationToken> Serialize(string name, object obj) {
    211 
    212188      object value = obj;
    213189      if (value == null)
     
    216192      if (obj2id.ContainsKey(value))
    217193        return ReferenceEnumerator(name, obj2id[value]);
    218       bool emitTypeInfo = false;
    219       if (!typeCache.ContainsKey(type)) {
    220         typeCache.Add(type, typeCache.Count);
    221         emitTypeInfo = InterleaveTypeInformation;
    222       }
    223       int typeId = typeCache[type];
     194      int typeId = typeCache.GetOrCreateId(type);
    224195      int? id = null;
    225196      if (!type.IsValueType) {
     
    230201        objectGraphTrace.Push(name);
    231202        IPrimitiveSerializer primitiveSerializer = configuration.GetPrimitiveSerializer(type);
    232         if (primitiveSerializer != null)
     203        if (primitiveSerializer != null) {
     204          typeCache.SetSerializer(typeId, primitiveSerializer.GetType());
    233205          return PrimitiveEnumerator(
    234206            name,
    235207            typeId,
    236208            primitiveSerializer.Format(value),
    237             id,
    238             emitTypeInfo);
     209            id);
     210        }
    239211        ICompositeSerializer compositeSerializer = configuration.GetCompositeSerializer(type);
     212        typeCache.SetSerializer(typeId, compositeSerializer.GetType());
    240213        if (compositeSerializer != null)
    241214          return CompositeEnumerator(
     
    244217            id,
    245218            typeId,
    246             compositeSerializer.CreateMetaInfo(value),
    247             emitTypeInfo);
    248         throw CreatePersistenceException(type, "Could not determine how to serialize a value.");
    249       }
    250       catch (Exception x) {
     219            compositeSerializer.CreateMetaInfo(value));
     220        throw CreatePersistenceException(type, "Could not determine how to serialize a value.", null);
     221      } catch (Exception x) {
    251222        if (isTestRun) {
    252223          exceptions.Add(x);
     
    255226          throw;
    256227        } else {
    257           throw CreatePersistenceException(type, "Uncaught exception during serialization: " + x.Message);
     228          throw CreatePersistenceException(type, "Uncaught exception during serialization: ", x);
    258229        }
    259       }
    260       finally {
     230      } finally {
    261231        objectGraphTrace.Pop();
    262232      }
    263233    }
    264234
    265     private PersistenceException CreatePersistenceException(Type type, string message) {
     235    private PersistenceException CreatePersistenceException(Type type, string message, Exception x) {
    266236      StringBuilder sb = new StringBuilder();
    267237      sb.Append(message)
     
    295265    }
    296266
    297     private IEnumerator<ISerializationToken> PrimitiveEnumerator(string name,
    298         int typeId, ISerialData serializedValue, int? id, bool emitTypeInfo) {
    299       if (emitTypeInfo) {
    300         var mapping = TypeCache[typeId];
    301         yield return new TypeToken(mapping.Id, mapping.TypeName, mapping.Serializer);
     267    private IEnumerator<ISerializationToken> PrimitiveEnumerator(string name, int typeId, ISerialData serializedValue, int? id) {
     268      if (InterleaveTypeInformation) {
     269        if (typeCache.HasUnpublishedType)
     270          yield return typeCache.PublishUnpublishedType();
     271        if (typeCache.HasUnpublishedSerializer)
     272          yield return typeCache.PublishUnpublishedSerializer();
    302273      }
    303274      yield return new PrimitiveToken(name, typeId, id, serializedValue);
    304275    }
    305276
    306     private IEnumerator<ISerializationToken> CompositeEnumerator(
    307         string name, IEnumerable<Tag> tags, int? id, int typeId, IEnumerable<Tag> metaInfo,
    308         bool emitTypeInfo) {
    309       if (emitTypeInfo) {
    310         var mapping = TypeCache[typeId];
    311         yield return new TypeToken(mapping.Id, mapping.TypeName, mapping.Serializer);
     277    private IEnumerator<ISerializationToken> CompositeEnumerator(string name, IEnumerable<Tag> tags, int? id, int typeId, IEnumerable<Tag> metaInfo) {
     278      if (InterleaveTypeInformation) {
     279        if (typeCache.HasUnpublishedType)
     280          yield return typeCache.PublishUnpublishedType();
     281        if (typeCache.HasUnpublishedSerializer)
     282          yield return typeCache.PublishUnpublishedSerializer();
    312283      }
    313284      yield return new BeginToken(name, typeId, id);
     
    335306        }
    336307      }
    337       yield return new EndToken(name, typeId, id);
     308      yield return new EndToken();
    338309    }
    339310  }
  • branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Core/Tokens/TypeToken.cs

    r5445 r6737  
    4040
    4141    /// <summary>
    42     /// The full type name of the serialized used to
    43     /// serialize the type.
    44     /// </summary>
    45     public readonly string Serializer;
    46 
    47     /// <summary>
    4842    /// Initializes a new instance of the <see cref="TypeToken"/> class.
    4943    /// </summary>
     
    5246    /// <param name="serializer">The full name of the serializer
    5347    /// used to serialize the type.</param>
    54     public TypeToken(int id, string typeName, string serializer) {
     48    public TypeToken(int id, string typeName) {
    5549      Id = id;
    5650      TypeName = typeName;
    57       Serializer = serializer;
    5851    }
    5952  }
Note: See TracChangeset for help on using the changeset viewer.