缓存多个密钥哈希

caching multiple key hash

本文关键字:哈希 密钥 缓存      更新时间:2023-10-16

我想在我的项目中做一些缓存。

让我的 API int foo(int a, float b, float c, int d, char e)

现在在我的项目中,有很多对上述耗时的 API 的调用,重复 a、b、c、d 和 e 的值。现在我想使用这些参数作为键来存储此函数的返回值。

假设我的调用序列是

foo(23, 3.45, 4.5, 90, 'd') // returns 1000, so I need to store it in cache as (23,3.45, 4.5, 90, 'd')->1000
foo(30, 1.2, 3.5, 100, 'e') // returns 2000, so I need to store it in cache as (30, 1.2, 3.5, 100, 'e')->2000
foo(23, 3.45, 4.5, 90, 'd') // No need to call this API, I just check in my cache value associated with    
//(23, 3.45, 4.5, 90, 'd'), which is already stored as 1000

在C++中实现上述最佳策略应该是什么? 哪种数据结构最适合制作缓存表?

一个关键说明:缓存很困难。

很多时候,人们认为缓存可以解决他们所有的问题,但他们忘记考虑它带来的问题。非托管缓存只不过是一个巨大的内存泄漏。两个值得注意的策略:

  • 大小限制:每当缓存已满时,添加新条目会导致另一个条目被逐出(因此您需要一个方案来决定何时逐出条目(
  • 时间
  • 限制:经过一定时间后,条目将被清除

通常,当我们听到缓存时,我们会想到LRU(最近最少使用(缓存。这些缓存受大小限制,当缓存已满时,将逐出最近最少使用的条目。注意:可能会导致多线程争用,因为只读访问实际上意味着修改值

这样的缓存是根据两个元素实现的:

  • (键 -> 值(映射,使用树或哈希映射
  • 优先级列表,在节点内交错以提高效率

如果你走这条路,我建议使用Boost.MultiIndex库。有一个 MRU 实现的示例,它与你的需求非常相似。

如果你可以使用boost,请查看boost::unordered_map,否则你可以使用std::map。您必须提供函子才能生成密钥。

它并不总是有效,并且在某种程度上依赖于编译器,但您可以考虑使用函数属性。 您可能感兴趣的是 const属性。 也可能感兴趣。

好问题。您有几种选择。首先,将所有值放入一个结构中:

struct values
{
   int a;
   float b;
    ...
};
  1. 如果序列的某个值最具代表性,则只需使用std::map将该代表性值映射到"存储桶"。假设最具代表性的是float b:

    std::map< float, std::list < std::pair< values, int> > >

    std::list 表示,并存储值结构和结果值对(在本例中int(。

  2. 声明从值到结果的映射,int .为此,您应该允许将结构values与映射中的其他结构进行比较,因此您必须编写operator<()

 int operator<(values const& left, values const& right)
 {
    if (left.a < left.b) ... // compare two values objects
 }

然后像往常一样声明地图:

std::map<values, int>

还有其他问题,例如复制构造函数等,您必须处理,但这就是想法。

最后要注意的是,您还可以用std::map代替unordered_map

将它们全部放在一个结构中

struct mykey{ int a; float b; float c; int d; char e; };

然后将它们写入并散列结构,并将其用作键

int foo(int a, float b, float c, int d, char e)
{
    mykey tk = { a, b, c, d, e };
    guid key = md5( &tk, sizeof( tk ) );

我会使用嵌套地图,所以你使用第一个参数从地图中查找地图,直到使用最后一个参数查找的最终地图,结果是以前缓存的 foo 值。

当您到达最后一个地图并发现尚未为此参数设置调用 foo 时,您只需存储最后一个参数的 foo 结果。

我建议使用哈希表。您只需要计算数据的哈希函数。如果哈希足够强大,则可以存储它并输出值,而无需存储参数。此外,这个 metod 应该比使用 std::map 工作得更快。

在C++这可以通过unordered_map或std::hash_map来实现。使用非常简单的哈希函数就足够了,例如字符串哈希函数。

顺便说一下,存储参数输出值的 metod 称为记忆