Exemplo n.º 1
0
        public static Func <FastDictionary2 <TKey, TValue> > CreateFastDictionary2Generator <TKey, TValue>(
            this IEqualityComparerExpression <TKey> comparerExp, int capacity, Func <TKey, TKey, bool> equalsFunc, Func <TKey, int> getHashCodeFunc, QueryContainer container)
        {
            if (EqualityComparerExpression <TKey> .IsSimpleDefault(comparerExp))
            {
                return(() => new FastDictionary2 <TKey, TValue>());
            }
            if (container == null)
            {
                return(() => new FastDictionary2 <TKey, TValue>(capacity, equalsFunc, getHashCodeFunc));
            }

            var equalsExp      = comparerExp.GetEqualsExpr();
            var getHashCodeExp = comparerExp.GetGetHashCodeExpr();
            var vars           = VariableFinder.Find(equalsExp).Select(o => o.GetHashCode()).ToList();

            if (!vars.Any())
            {
                vars.Add(string.Empty.StableHash());
            }
            var hashvars = VariableFinder.Find(getHashCodeExp).Select(o => o.GetHashCode()).ToList();

            if (!hashvars.Any())
            {
                hashvars.Add(string.Empty.StableHash());
            }
            var key =
                Tuple.Create(
                    equalsExp.ToString() + getHashCodeExp.ToString() + string.Concat(vars.Aggregate((a, i) => a ^ i)) + string.Concat(hashvars.Aggregate((a, i) => a ^ i)),
                    typeof(TKey), typeof(TValue));

            Type temp;

            lock (sentinel)
            {
                if (!generatorCache.TryGetValue(key, out temp))
                {
                    string typeName    = Prefix + classCounter++;
                    var    builderCode = new GeneratedFastDictionary(typeName, "2").TransformText();
                    var    a           = Transformer.CompileSourceCode(builderCode, Array.Empty <Assembly>(), out string errorMessages);

                    temp = a.GetType(typeName + "`2");
                    temp = temp.MakeGenericType(typeof(TKey), typeof(TValue));
                    MethodInfo init = temp.GetTypeInfo().GetMethod("Initialize", BindingFlags.Static | BindingFlags.Public);
                    init.Invoke(null, new object[] { equalsFunc, getHashCodeFunc, capacity });
                    generatorCache.Add(key, temp);
                }
                if (!container.TryGetFastDictionary2Type(key, out Type other))
                {
                    container.RegisterFastDictionary2Type(key, temp);
                }
            }

            return(() => (FastDictionary2 <TKey, TValue>)Activator.CreateInstance(temp));
        }
Exemplo n.º 2
0
        public static Expression <Func <SortedDictionary <TKey, TValue> > > CreateSortedDictionaryGenerator <TKey, TValue>(this IComparerExpression <TKey> comparerExp, QueryContainer container)
        {
            if (ComparerExpression <TKey> .IsSimpleDefault(comparerExp))
            {
                return(() => new SortedDictionary <TKey, TValue>());
            }

            var expr = comparerExp.GetCompareExpr();

            if (container == null)
            {
                Expression <Func <Comparison <TKey>, SortedDictionary <TKey, TValue> > > template
                    = (c) => new SortedDictionary <TKey, TValue>(Comparer <TKey> .Create(c));
                var replaced = template.ReplaceParametersInBody(expr);
                return(Expression.Lambda <Func <SortedDictionary <TKey, TValue> > >(replaced));
            }

            var expression = expr.ToString();
            var vars       = VariableFinder.Find(expr).Select(o => o.GetHashCode());
            var captures   = vars.Aggregate(expression.GetHashCode(), (a, i) => a ^ i);
            var key        = Tuple.Create(expression + string.Concat(vars.Select(o => o.ToString(CultureInfo.InvariantCulture))), typeof(TKey), typeof(TValue));

            Type temp;

            lock (sentinel)
            {
                if (!DictionaryTypes.TryGetValue(key, out temp))
                {
                    string typeName = Prefix
                                      + captures.ToString(CultureInfo.InvariantCulture)
                                      + typeof(TKey).ToString().GetHashCode().ToString(CultureInfo.InvariantCulture)
                                      + typeof(TValue).ToString().GetHashCode().ToString(CultureInfo.InvariantCulture);
                    typeName = typeName.Replace("-", "_");
                    var builderCode        = new GeneratedSortedDictionary(typeName).TransformText();
                    var assemblyReferences = Transformer.AssemblyReferencesNeededFor(typeof(SortedDictionary <,>));
                    var a = Transformer.CompileSourceCode(builderCode, assemblyReferences, out string errorMessages);

                    temp = a.GetType(typeName + "`2");
                    temp = temp.MakeGenericType(typeof(TKey), typeof(TValue));
                    var init = temp.GetTypeInfo().GetMethod("Initialize", BindingFlags.Static | BindingFlags.Public);
                    init.Invoke(null, new object[] { Comparer <TKey> .Create(expr.Compile()) });
                    DictionaryTypes.Add(key, temp);
                }
                if (!container.TryGetSortedDictionaryType(key, out Type other))
                {
                    container.RegisterSortedDictionaryType(key, temp);
                }
            }
            return(Expression.Lambda <Func <SortedDictionary <TKey, TValue> > >(Expression.New(temp)));
        }