/// <summary> /// Creates a serializer for the given type and settings. /// </summary> /// <typeparam name="TExample">The user type to serialize.</typeparam> /// <param name="settings"></param> /// <returns></returns> public static VowpalWabbitSerializerCompiled <TExample> CreateSerializer <TExample>(VowpalWabbitSettings settings = null) { List <FeatureExpression> allFeatures = null; Type cacheKey = null; if (settings != null && settings.AllFeatures != null) { allFeatures = settings.AllFeatures; } else { // only cache non-string generating serializer if (!settings.EnableStringExampleGeneration) { cacheKey = typeof(TExample); object serializer; if (SerializerCache.TryGetValue(cacheKey, out serializer)) { return((VowpalWabbitSerializerCompiled <TExample>)serializer); } } // TOOD: enhance caching based on feature list & featurizer set // if no feature mapping is provided, use [Feature] annotation on provided type. Func <PropertyInfo, FeatureAttribute, bool> propertyPredicate = null; switch (settings.FeatureDiscovery) { case VowpalWabbitFeatureDiscovery.Default: propertyPredicate = (_, attr) => attr != null; break; case VowpalWabbitFeatureDiscovery.All: propertyPredicate = (_, __) => true; break; } allFeatures = AnnotationInspector.ExtractFeatures(typeof(TExample), propertyPredicate).ToList(); } // need at least a single feature to do something sensible if (allFeatures == null || allFeatures.Count == 0) { return(null); } var newSerializer = new VowpalWabbitSerializerCompiled <TExample>( allFeatures, settings == null ? null : settings.CustomFeaturizer, !settings.EnableStringExampleGeneration); if (cacheKey != null) { SerializerCache[cacheKey] = newSerializer; } return(newSerializer); }
internal VowpalWabbitSerializer(VowpalWabbitSerializerCompiled <TExample> serializer, VowpalWabbit vw) { if (serializer == null) { throw new ArgumentNullException("serializer"); } Contract.Ensures(vw != null); Contract.EndContractBlock(); this.vw = vw; this.serializer = serializer; this.serializerFunc = serializer.Func(vw); var cacheableAttribute = (CacheableAttribute)typeof(TExample).GetCustomAttributes(typeof(CacheableAttribute), true).FirstOrDefault(); if (cacheableAttribute == null) { return; } if (this.vw.Settings.EnableExampleCaching) { if (cacheableAttribute.EqualityComparer == null) { this.exampleCache = new Dictionary <TExample, CacheEntry>(); } else { if (!typeof(IEqualityComparer <TExample>).IsAssignableFrom(cacheableAttribute.EqualityComparer)) { throw new ArgumentException( string.Format( CultureInfo.InvariantCulture, "EqualityComparer ({1}) specified in [Cachable] of {0} must implement IEqualityComparer<{0}>", typeof(TExample), cacheableAttribute.EqualityComparer)); } var comparer = (IEqualityComparer <TExample>)Activator.CreateInstance(cacheableAttribute.EqualityComparer); this.exampleCache = new Dictionary <TExample, CacheEntry>(comparer); } #if DEBUG this.reverseLookup = new Dictionary <VowpalWabbitExample, CacheEntry>(new ReferenceEqualityComparer <VowpalWabbitExample>()); #endif } }