Результаты Функции кэша

SQL Server 2005, 2008, 2012, 2014 или 2016:

SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE'

Для показа только таблиц от конкретной базы данных

SELECT TABLE_NAME 
FROM <DATABASE_NAME>.INFORMATION_SCHEMA.TABLES 
WHERE TABLE_TYPE = 'BASE TABLE'

Или,

SELECT TABLE_NAME 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_TYPE = 'BASE TABLE' 
    AND TABLE_CATALOG='dbName' --(for MySql, use: TABLE_SCHEMA='dbName' )

пз: Для SQL Server 2000:

SELECT * FROM sysobjects WHERE xtype='U' 
7
задан Joel Coehoorn 22 July 2009 в 18:44
поделиться

3 ответа

Другое название этого автоматического кэширования результатов функции - мемоизация. Для открытого интерфейса рассмотрите что-нибудь в этом роде:

public Func<T,TResult> Memoize<T,TResult>(Func<T,TResult> f)

... и просто используйте полиморфизм для хранения T в словаре объекта.

Расширение диапазона делегатов можно реализовать с помощью каррирования и частичного применения функций. Примерно так:

static Func<T1,Func<T2,TResult>> Curry(Func<T1,T2,TResult> f)
{
    return x => y => f(x, y);
}
// more versions of Curry

Поскольку Карри превращает функции с несколькими аргументами в функции с одним аргументом (но которые могут возвращать функции), возвращаемые значения могут быть запомнены сами.

Другой способ сделать это. было бы использовать отражение для проверки типа делегата и хранить кортежи в словаре, а не просто тип аргумента. Упрощенный кортеж будет просто оберткой массива, в которой хэш-код и логика равенства используют глубокие сравнения и хеширование.

Сделать недействительность можно с помощью слабых ссылок, но создание словарей с ключами WeakReference сложно - лучше всего это делать с поддержкой среды выполнения (значения WeakReference намного проще). Я считаю, что существуют некоторые реализации.

Безопасность потоков легко достигается за счет блокировки внутреннего словаря для событий мутации, но наличие словаря без блокировки может повысить производительность в сильно параллельных сценариях. Этот словарь, вероятно, будет еще труднее создать - хотя есть интересная презентация для Java здесь .

Я считаю, что существуют некоторые реализации.

Безопасность потоков легко достигается за счет блокировки внутреннего словаря для событий мутации, но наличие словаря без блокировки может повысить производительность в сильно параллельных сценариях. Этот словарь, вероятно, будет еще труднее создать - хотя есть интересная презентация для Java здесь .

Я считаю, что существуют некоторые реализации.

Безопасность потоков легко достигается за счет блокировки внутреннего словаря для событий мутации, но наличие словаря без блокировки может повысить производительность в сильно параллельных сценариях. Этот словарь, вероятно, будет еще труднее создать - хотя есть интересная презентация для Java здесь .

8
ответ дан 7 December 2019 в 01:25
поделиться

Вау - какая интуиция - я недавно задал вопрос о непрозрачных ключах в C # ... и потому что я Пытаюсь реализовать что-то связанное с кешированием результатов функций. Как весело.

Этот тип метапрограммирования может быть сложным с C # ... особенно потому, что параметры универсального типа могут привести к неудобному дублированию кода. Вам часто приходится повторять почти один и тот же код в нескольких местах с разными параметрами типа для достижения безопасности типов.

Итак, вот мой вариант вашего подхода, который использует мой непрозрачный ключевой шаблон и замыкания для создания кэшируемых функций. В приведенном ниже примере демонстрируется шаблон с одним или двумя аргументами, но его относительно легко расширить. Он также использует методы расширения для создания прозрачного шаблона для обертывания Func <> с кэшируемым Func <> с помощью метода AsCacheable () . Замыкания захватывают кеш, связанный с функцией, и делают его существование прозрачным для других вызывающих.

Этот метод имеет многие из тех же ограничений, что и ваш подход (безопасность потоков, привязка к ссылкам и т. Д.) - я подозреваю, что их несложно преодолеть - но он ДЕЙСТВИТЕЛЬНО поддерживает простой способ расширения до нескольких параметров, и это позволяет кешируемым функциям быть полностью заменяемыми обычными - поскольку они являются просто делегатом оболочки.

Также стоит отметить, что если вы создаете второй экземпляр CacheableFunction - вы получаете отдельный кеш. Это может быть как сильной стороной, так и недостатком ... поскольку в некоторых ситуациях вы можете не осознавать, что это происходит.

Вот код:

public interface IFunctionCache
{
    void InvalidateAll();
    // we could add more overloads here...
}

public static class Function
{
    public class OpaqueKey<A, B>
    {
        private readonly object m_Key;

        public A First { get; private set; }
        public B Second { get; private set; }

        public OpaqueKey(A k1, B k2)
        {
            m_Key = new { K1 = k1, K2 = k2 };
            First = k1;
            Second = k2;
        }

        public override bool Equals(object obj)
        {
            var otherKey = obj as OpaqueKey<A, B>;
            return otherKey == null ? false : m_Key.Equals(otherKey.m_Key);
        }

        public override int GetHashCode()
        {
            return m_Key.GetHashCode();
        }
    }

    private class AutoCache<TArgs,TR> : IFunctionCache
    {
        private readonly Dictionary<TArgs,TR> m_CachedResults 
            = new Dictionary<TArgs, TR>();

        public bool IsCached( TArgs arg1 )
        {
            return m_CachedResults.ContainsKey( arg1 );
        }

        public TR AddCachedValue( TArgs arg1, TR value )
        {
            m_CachedResults.Add( arg1, value );
            return value;
        }

        public TR GetCachedValue( TArgs arg1 )
        {
            return m_CachedResults[arg1];
        }

        public void InvalidateAll()
        {
            m_CachedResults.Clear();
        }
    }

    public static Func<A,TR> AsCacheable<A,TR>( this Func<A,TR> function )
    {
        IFunctionCache ignored;
        return AsCacheable( function, out ignored );
    }

    public static Func<A, TR> AsCacheable<A, TR>( this Func<A, TR> function, out IFunctionCache cache)
    {
        var autocache = new AutoCache<A,TR>();
        cache = autocache;
        return (a => autocache.IsCached(a) ?
                     autocache.GetCachedValue(a) :
                     autocache.AddCachedValue(a, function(a)));
    }

    public static Func<A,B,TR> AsCacheable<A,B,TR>( this Func<A,B,TR> function )
    {
        IFunctionCache ignored;
        return AsCacheable(function, out ignored);
    }

    public static Func<A,B,TR> AsCacheable<A,B,TR>( this Func<A,B,TR> function, out IFunctionCache cache )
    {
        var autocache = new AutoCache<OpaqueKey<A, B>, TR>();
        cache = autocache;
        return ( a, b ) =>
                   {
                       var key = new OpaqueKey<A, B>( a, b );
                       return autocache.IsCached(key)
                                  ? autocache.GetCachedValue(key)
                                  : autocache.AddCachedValue(key, function(a, b));
                   };
    }
}

public class CacheableFunctionTests
{
    public static void Main( string[] args )
    {
        Func<string, string> Reversal = s => new string( s.Reverse().ToArray() );

        var CacheableReverse = Reversal.AsCacheable();

        var reverse1 = CacheableReverse("Hello");
        var reverse2 = CacheableReverse("Hello"); // step through to prove it uses caching

        Func<int, int, double> Average = (a,b) => (a + b)/2.0;
        var CacheableAverage = Average.AsCacheable();

        var average1 = CacheableAverage(2, 4);
        var average2 = CacheableAverage(2, 4);
    }
}
2
ответ дан 7 December 2019 в 01:25
поделиться

Поскольку это в основном для образовательных целей - вам следует взглянуть на класс WeakReference, который позволяет сборщику мусора удалять неиспользуемые дескрипторы из вашего класса в многопоточной среде. Это довольно распространенный шаблон кеширования в .NET

Тем не менее - Caveat Emptor! Каждый кеш отличается. Создавая комплексное решение, вы часто попадаете в патологический случай, когда ваш «кеш» представляет собой просто прославленный словарь с множеством сложных вспомогательных методов, которые затрудняют чтение вашего кода.

0
ответ дан 7 December 2019 в 01:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: