Arhn - архитектура программирования

Генерация ключа кэша (уникального ключа) для хеша

У меня есть хэш, например:

filers = {query: 'nice post', sort: 'time_desc', post_type: 'blog'...limit: 100}

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

25.04.2014

  • Может ли это работать? ruby-doc. org/stdlib-1.9.3/libdoc/securerandom/rdoc/ 25.04.2014
  • О каком ответе вы говорите? 25.04.2014
  • @sawa, я упомянул ответ как результат внешнего вызова API с использованием указанной выше комбинации фильтров. Да, я использую memcache для кэширования ответа. 25.04.2014

Ответы:


1

Рассмотрим следующие два шага:

  1. Преобразуйте хэш в строку (или другой сериализованный формат) после сортировки выходного порядка записи на основе ключа.

    Важно, чтобы значения сортировались по ключу во время этого преобразования, чтобы хэши с одинаковыми парами ключ/значение (но с другим порядком ключей) давали одинаковый результат. Более сложные/вложенные структуры требуют дополнительной обработки и должны обеспечивать непротиворечивый вывод для эквивалентных объектов.

    Чтобы начать процесс, подумайте:

    sorted_kv_pairs = hash.to_a.sort_by {|k,v| k.to_s}
    
  2. Используйте функцию хеширования, такую ​​как SHA-1 или SHA-256/160, для создания 40-байтового уникального идентификатора из ранее сериализованного объекта.

    Огромное пространство вывода (и криптографические качества) этих функций делают невозможным целенаправленное столкновение и, таким образом, приводят к "уникальным идентификаторам".

25.04.2014
  • Я бы рекомендовал использовать решение 2 выше. 25.04.2014
  • Моя ошибка. Да. Я согласен. Шаг 1, затем Шаг 2. 25.04.2014
  • Вы также можете использовать другие алгоритмы хеширования: programmers.stackexchange.com/a/145633/82539 25.04.2014
  • @UriAgassi Спасибо за ссылку. Это удобный ответ/ссылка. Однако я бы использовал криптографическую хеш-функцию с большим выходным пространством. Эти функции хеширования/контрольной суммы (32-битный вывод) служат другой цели (очень быстрая контрольная сумма или первичный хеш со вторичным равенством), но имеют гораздо меньшие гарантии уникальности. Хотя у них не так много коллизий и они хорошо распределяются по случайному вводу (~ 200 000), они намного чаще генерируют дубликаты, чем SHA/криптографический хэш, из-за проблемы дня рождения. 25.04.2014

  • 2

    Простым решением будет использование класса Marshal для создания дампа и чтения содержимое. Для больших масштабов вы можете использовать memcached, для которого есть несколько оболочек Ruby, или некоторые базы данных типа «ключ-значение», такие как redis, neo4j.

    25.04.2014

    3

    Вот мое решение, основанное на этом ответе

    # Return a cache key based on params hash
    def params_cache_key(params)
      # Normalize parameter hash, change keys to a string, normalize key order, sort array values
      normalized = params.transform_keys(&:to_s)
                       .transform_values { |v| v.is_a?(Array) ? v.sort : v }
                       .sort_by { |k, _| k }.each_with_object('') do |(k, v), cache_key|
        cache_key << "#{k}:#{v}"
      end
      Digest::SHA1.hexdigest(normalized)
    end
    

    И вот несколько тестовых случаев

    describe '#params_cache_key' do
    
      def cache_key(params)
        controller.send :params_cache_key, params
      end
    
      it 'should produce a sha1' do
        expect(cache_key(foo: 'bar', bar: 'baz')).to match /^\h{40}$/
      end
    
      it 'should produce same hash for different key order' do
        expect(cache_key(foo: 'bar', bar: 'baz')).to eq cache_key(bar: 'baz', foo: 'bar')
      end
    
      it 'should produce same hash for stringified keys' do
        expect(cache_key(foo: 'bar', bar: 'baz')).to eq cache_key(foo: 'bar', 'bar' => 'baz')
      end
    
      it 'should work with nested parameters in different order' do
        expect(cache_key(category: %w(foo bar))).to eq cache_key(category: %w(bar foo))
      end
    
    end
    
    14.03.2017
  • Да, этот код скоро усложнится. Не забывайте о вложенных массивах и хешах. Поэтому я бы сказал, что невозможно гарантировать, что одни и те же данные будут генерировать один и тот же хеш, учитывая разные порядки сортировки. Просто сортировать по ключу первого уровня должно быть достаточно. 30.04.2018
  • ваш метод cache_key в спецификации относится к controller , удалите его 30.04.2018
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..