什么是生成ETag的有效且处理成本低廉的算法?

时间:2015-09-29 06:43:46

标签: c# rest http nancy etag

我有一个REST API(内置在Nancy中,在ASP.NET上运行),可以返回这样的JSON对象:

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

请注意,此对象不是直接实体,而是表示。

通常,我会使用DB中实体的最后修改/时间戳作为ETag,然后当它更新时,ETag会更新。简单。

但在这种情况下,如果用户没有改变,但第一次评论的内容发生了变化,该怎么办?使用上述ETag逻辑,它不会改变。我们在这里有一个案例,其中表示包括多个实体,并且我试图找到一种方法来唯一地识别它。

所以我需要以某种方式识别该表示(这是一个简单的C#POCO,存储在Redis缓存中)。

以下是我最初的想法:

  • Object.GetHashCode()。不会工作,因为内存参考总是不同的。
  • 内存流对象,SHA1散列它。每次都要花钱。
  • 在添加/更新缓存之前,创建一个用于ETag的GUID,并将其存储在缓存中。然后,当高速缓存被刷新时(在前面的示例中将会刷新),生成新的GUID并更新ETag。这种方法的问题在于我将我的ETag机制绑定到我的缓存实现(因此没有松散耦合)。

有没有人能想到一种廉价/有效的方法来做到这一点,理想情况是在全球范围内? (例如Object或基础对象,而不是每个实体/资源的特定ETag生成逻辑。

非常感谢!

1 个答案:

答案 0 :(得分:1)

我认为哈希方法并不是那么糟糕。我会考虑有极其高效的哈希算法,如MurmurHash3(128位版本)和xxHash(64位版本)。这是一种有效的方法,但不幸的是它并不是最便宜的。您可以找到c#implements herehere

您说数据库中的每个实体都有一个修改过的时间戳。如果模型由多个实体组成,则模型ETag可以从实体时间戳导出。模型ETag将是实体时间戳的串联。这种方法效率更高,但你无法做到这一点,你需要为每个模型编写特定的代码。