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

本文关键字:算法 是什么 处理 etag 有效 生成 | 更新日期: 2023-09-27 18:15:04

我有一个REST API(内置在Nancy中,运行在ASP.NET上),它可以返回一个JSON对象,如下所示:

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

注意这个对象不是一个直接的实体,而是一个表示。

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

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

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

这是我最初的想法:

  • Object.GetHashCode()。不能工作,因为内存引用总是不同的。
  • 内存流对象,SHA1哈希它。每次都很昂贵。
  • 在我添加/更新缓存之前,创建一个用于ETag的GUID并将其存储在缓存中。然后,当缓存被刷新时(在前面的示例中就是这样),将生成一个新的GUID,并更新ETag。这种方法的问题是我将ETag机制绑定到我的缓存实现(所以不是松耦合)。

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

多谢!

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

我认为哈希方法并没有那么糟糕。我会考虑一些非常高效的散列算法,比如MurmurHash3(128位版本)和xxHash(64位版本)。这是一种有效的方法,但不幸的是,它不是最便宜的。你可以在这里和这里找到c#实现。

您说数据库中的每个实体都有一个修改过的时间戳。如果模型由多个实体组成,则可以从实体时间戳派生模型ETag。模型ETag将是实体时间戳的连接。这种方法更有效,但您不能全局地执行,您需要为每个模型编写特定的代码。