Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
03/10/10 15:27:10 (14 years ago)
Author:
epitzer
Message:

add caches for hooks (#900)

Location:
trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableAttribute.cs

    r1960 r2991  
    8888
    8989    public static IEnumerable<StorableMemberInfo> GetStorableMembers(Type type, bool inherited) {
    90       var query = new TypeQuery(type, inherited);
    91       if (memberCache.ContainsKey(query))
    92         return memberCache[query];
    93       var storablesMembers = GenerateStorableMembers(type, inherited);
    94       memberCache[query] = storablesMembers;
    95       return storablesMembers;
     90      lock (memberCache) {
     91        var query = new TypeQuery(type, inherited);
     92        if (memberCache.ContainsKey(query))
     93          return memberCache[query];
     94        var storablesMembers = GenerateStorableMembers(type, inherited);
     95        memberCache[query] = storablesMembers;
     96        return storablesMembers;
     97      }
    9698    }
    9799
     
    101103        storableMembers.AddRange(GenerateStorableMembers(type.BaseType, true));
    102104      foreach (MemberInfo memberInfo in type.GetMembers(instanceMembers)) {
    103         foreach (object attribute in memberInfo.GetCustomAttributes(false)) {
    104           StorableAttribute storableAttribute = attribute as StorableAttribute;
    105           if (storableAttribute != null) {
    106             storableMembers.Add(new StorableMemberInfo(storableAttribute, memberInfo));
    107           }
     105        foreach (StorableAttribute attribute in memberInfo.GetCustomAttributes(typeof(StorableAttribute), false)) {         
     106          storableMembers.Add(new StorableMemberInfo(attribute, memberInfo));         
    108107        }
    109108      }
  • trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableConstructorAttribute.cs

    r2983 r2991  
    1212
    1313    private static readonly BindingFlags allConstructors =
    14       BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
     14      BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;   
    1515
    16     private static readonly object[] defaultArgs = new object[] { true };
     16    private static Dictionary<Type, ConstructorInfo> constructorCache =
     17      new Dictionary<Type, ConstructorInfo>();
    1718
    18     public static object CallStorableConstructor(Type type) {
    19       foreach (ConstructorInfo constructorInfo in type.GetConstructors(allConstructors)) {
    20         if (constructorInfo
    21           .GetCustomAttributes(typeof(StorableConstructorAttribute), false).Length > 0) {
    22           if (constructorInfo.GetParameters().Length != 1 ||
    23               constructorInfo.GetParameters()[0].ParameterType != typeof(bool))
    24             throw new PersistenceException("StorableConstructor must have exactly one argument of type bool");
    25           return constructorInfo.Invoke(defaultArgs);
     19    public static ConstructorInfo GetStorableConstructor(Type type) {
     20      lock (constructorCache) {
     21        if (constructorCache.ContainsKey(type))
     22          return constructorCache[type];
     23        foreach (ConstructorInfo ci in type.GetConstructors(allConstructors)) {
     24          if (ci.GetCustomAttributes(typeof(StorableConstructorAttribute), false).Length > 0) {
     25            if (ci.GetParameters().Length != 1 ||
     26                ci.GetParameters()[0].ParameterType != typeof(bool))
     27              throw new PersistenceException("StorableConstructor must have exactly one argument of type bool");
     28            constructorCache[type] = ci;
     29            return ci;
     30          }
    2631        }
     32        constructorCache[type] = null;
     33        return null;
    2734      }
    28       return null;
    2935    }
    30 
    3136  }
    3237}
  • trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableHookAttribute.cs

    r2983 r2991  
    1111  [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
    1212  public sealed class StorableHookAttribute : Attribute {
     13
     14    private sealed class HookDesignator {
     15      public Type Type { get; set; }
     16      public HookType HookType { get; set; }
     17      public HookDesignator() { }
     18      public HookDesignator(Type type, HookType hookType) {
     19        Type = type;
     20        HookType = HookType;
     21      }
     22    }
    1323
    1424    private readonly HookType hookType;
     
    2636    private static readonly object[] emptyArgs = new object[] { };
    2737
     38    private static Dictionary<HookDesignator, List<MethodInfo>> hookCache =
     39      new Dictionary<HookDesignator, List<MethodInfo>>();
     40
    2841    public static void InvokeHook(HookType hookType, object obj) {
    2942      if (obj == null)
    3043        throw new ArgumentNullException("Cannot invoke hooks on null");
    31       Type type = obj.GetType();
     44      foreach (MethodInfo mi in GetHooks(hookType, obj.GetType())) {
     45        mi.Invoke(obj, emptyArgs);
     46      }
     47    }
     48
     49    private static IEnumerable<MethodInfo> GetHooks(HookType hookType, Type type) {
     50      lock (hookCache) {
     51        List<MethodInfo> hooks;
     52        var designator = new HookDesignator(type, hookType);
     53        hookCache.TryGetValue(designator, out hooks);
     54        if (hooks != null)
     55          return hooks;
     56        hooks = new List<MethodInfo>(CollectHooks(hookType, type));
     57        hookCache.Add(designator, hooks);
     58        return hooks;
     59      }
     60    }
     61
     62    private static IEnumerable<MethodInfo> CollectHooks(HookType hookType, Type type) {     
    3263      foreach (MemberInfo memberInfo in type.GetMembers(instanceMembers)) {
    33         foreach (StorableHookAttribute hook in memberInfo.GetCustomAttributes(typeof(StorableHookAttribute), false)) {         
     64        foreach (StorableHookAttribute hook in memberInfo.GetCustomAttributes(typeof(StorableHookAttribute), false)) {
    3465          if (hook != null && hook.HookType == hookType) {
    3566            MethodInfo methodInfo = memberInfo as MethodInfo;
    3667            if (memberInfo.MemberType != MemberTypes.Method || memberInfo == null)
    3768              throw new ArgumentException("Storable hooks must be methods");
    38             methodInfo.Invoke(obj, emptyArgs);
     69            yield return methodInfo;
    3970          }
    4071        }
  • trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableSerializer.cs

    r2990 r2991  
    1919      if (!ReflectionTools.HasDefaultConstructor(type))
    2020        return false;
    21       while (type != null) {       
     21      while (type != null) {
    2222        if (StorableAttribute.GetStorableMembers(type, false).Count() == 0 &&
    2323            !EmptyStorableClassAttribute.IsEmptyStorable(type))
     
    3939    }
    4040
     41    private static readonly object[] defaultArgs = new object[] { true };
     42
    4143    public object CreateInstance(Type type, IEnumerable<Tag> metaInfo) {
    4244      try {
    43         object instance = StorableConstructorAttribute.CallStorableConstructor(type);
    44         if (instance == null)
    45           instance = Activator.CreateInstance(type, true);
    46         return instance;
     45        ConstructorInfo constructor = StorableConstructorAttribute.GetStorableConstructor(type);
     46        return constructor != null ? constructor.Invoke(defaultArgs) :  Activator.CreateInstance(type, true);       
    4747      } catch (TargetInvocationException x) {
    4848        throw new PersistenceException(
Note: See TracChangeset for help on using the changeset viewer.