2015-09-29 3 views
5

У меня есть REST API (построен в Нанси, работает на ASP.NET), что может вернуть объект JSON как это:Что такое эффективный и дешевый алгоритм для генерации ETags?

{ 
    id: "1", 
    name: "Fred", 
    reviews: [ 
    { 
     id: "10", 
     content: "I love Stack Overflow" 
    } 
    ] 
} 

Обратите внимание, как этот объект не является прямым лицом, а это представление.

Обычно я использовал бы последнюю измененную/временную метку объекта в БД как ETag, а затем, когда он будет обновлен, ETag будет обновляться. Просто.

Но в этом случае, что, если пользователь не изменится, но содержимое первого обзора изменится? Используя вышеупомянутую логику ETag, она не изменится. Здесь у нас есть случай, когда представление включает несколько объектов, и я пытаюсь найти способ однозначно идентифицировать это.

Так что мне нужно как-то идентифицировать это представление (которое является простым C# POCO, хранящимся в кеше Redis).

Вот мои первые мысли:

  • Object.GetHashCode(). Не будет работать, потому что ссылка на память всегда будет отличаться.
  • Память потока объекта, SHA1 хэш его. Достойно делать каждый раз.
  • Прежде чем добавить/обновить кеш, создайте GUID, который будет использоваться для ETag, и сохраните его в кеше. Затем, когда кеш-память будет сброшена (что было бы в предыдущем примере), будет создан новый GUID и обновится ETag. Проблема с этим подходом заключается в том, что я привязываю свой механизм ETag к моей реализации кэширования (поэтому не связан с ним).

Может ли кто-нибудь подумать о дешевом/эффективном способе сделать это, идеально на глобальном уровне? (например, Object или базовый объект вместо конкретной логики генерации ETag для каждого объекта/ресурса).

Большое спасибо!

ответ

1

Я думаю, что подход хэширования не так уж плох. Существуют экстремально эффективные алгоритмы хэша, такие как MurmurHash3 (128-разрядная версия) и xxHash (64-разрядная версия), которые я бы рассмотрел. Это эффективный способ сделать это по-глобальному, но, к сожалению, он не самый дешевый. Вы можете найти реализации C# here и here.

Вы сказали, что каждая сущность в базе данных имеет модифицированную метку времени. Если модель состоит из нескольких объектов, модель ETag может быть получена из временных меток сущностей. Модель ETag была бы конкатенацией временных меток сущностей. Этот подход более эффективен, но вы не можете сделать это по-глобальному, вам нужно будет написать конкретный код для каждой модели.