功能为"均匀分布"跨越可能值的空间的序号

时间:2014-09-22 20:53:53

标签: hash sequential

我需要在Google AppEngine中存储一堆实体(或者你可以想到任何其他哈希表),我需要从顺序输入创建自己的键。

作为一个例子,假设我只处理长度为一位十进制数的密钥。然后我需要存储一个用于键'0'的实体,一个用于键'1',一个用于键'2',依此类推。

问题在于,如果我只是直接使用这个增加的序列作为键,它将导致所有实体在物理上彼此非常靠近地存储,这可能导致严重的性能问题。 Details here。对于一般的散列表,您可以认为所有条目并非均匀分布在所有存储桶上,而是集中在几个存储桶中,这也会导致查找性能下降等。

所以,我正在寻找一些功能,以便在可用值的空间内更均匀地“重新分配”我的值。

为了保持单位数键的例子,我可以创建一个包含所有可能值的随机排列的表,如[5,9,2,4,1,8,0,6,3] ,7]和索引。然后,当我存储将彼此相邻的条目0,1和2时,我将分配更多分散在服务器或散列桶中的密钥5,9和2。

但我需要找到一种方法来为156位数字执行此操作,在这种情况下,所有值的随机排列的表是不可行的。

我有两个要求:

  • 每个可能的156位数字必须映射到正好一个值(最多160位就可以)。没有碰撞允许
  • 这应该是计算上便宜的

我找到了一种方法:只需使用SHACAL-1或其他160位密码“加密”我的值。但这对于我正在努力实现的目标来说似乎是太多的计算工作。是否有一些伪随机函数可以用我的值作为种子?他们会保证免受碰撞吗?

1 个答案:

答案 0 :(得分:3)

您可以使用离散对数,它为您提供所有阵列位置的完美确定性排列。但是,排列是单向的:您无法在不诉诸强力(或在允许的方向上重新排列)的情况下检索新的第i个阵列位置的原始位置

OR

如果您不关心额外的空间,您可以存储对<value-originalindex>并将它们完全随机放置(使用一些PRNG功能),以便在发生碰撞时重复(或记下已经使用过的地方) 。现在这些对均匀分布。检索第i个元素需要O(N),其中N是位数。这是该算法的代价。

OR

只获取156位值的几个随机位并使用它们来形成,比方说,12位无符号索引。使用此索引从最终空间中选择第k个存储桶(您的空间在2 ^ 12个存储区中分区)。只有当它们共享相同的12位随机位时,值才会聚合,如果你仔细选择它们,这是非常不可能的...使用剩余的156-12 = 143位来反映内部桶。

OR

创建156位的固定随机排列。