我需要在Google AppEngine中存储一堆实体(或者你可以想到任何其他哈希表),我需要从顺序输入创建自己的键。
作为一个例子,假设我只处理长度为一位十进制数的密钥。然后我需要存储一个用于键'0'的实体,一个用于键'1',一个用于键'2',依此类推。
问题在于,如果我只是直接使用这个增加的序列作为键,它将导致所有实体在物理上彼此非常靠近地存储,这可能导致严重的性能问题。 Details here。对于一般的散列表,您可以认为所有条目并非均匀分布在所有存储桶上,而是集中在几个存储桶中,这也会导致查找性能下降等。
所以,我正在寻找一些功能,以便在可用值的空间内更均匀地“重新分配”我的值。
为了保持单位数键的例子,我可以创建一个包含所有可能值的随机排列的表,如[5,9,2,4,1,8,0,6,3] ,7]和索引。然后,当我存储将彼此相邻的条目0,1和2时,我将分配更多分散在服务器或散列桶中的密钥5,9和2。
但我需要找到一种方法来为156位数字执行此操作,在这种情况下,所有值的随机排列的表是不可行的。
我有两个要求:
我找到了一种方法:只需使用SHACAL-1或其他160位密码“加密”我的值。但这对于我正在努力实现的目标来说似乎是太多的计算工作。是否有一些伪随机函数可以用我的值作为种子?他们会保证免受碰撞吗?
答案 0 :(得分:3)
您可以使用离散对数,它为您提供所有阵列位置的完美确定性排列。但是,排列是单向的:您无法在不诉诸强力(或在允许的方向上重新排列)的情况下检索新的第i个阵列位置的原始位置
OR
如果您不关心额外的空间,您可以存储对<value-originalindex>
并将它们完全随机放置(使用一些PRNG功能),以便在发生碰撞时重复(或记下已经使用过的地方) 。现在这些对均匀分布。检索第i个元素需要O(N),其中N是位数。这是该算法的代价。
OR
只获取156位值的几个随机位并使用它们来形成,比方说,12位无符号索引。使用此索引从最终空间中选择第k个存储桶(您的空间在2 ^ 12个存储区中分区)。只有当它们共享相同的12位随机位时,值才会聚合,如果你仔细选择它们,这是非常不可能的...使用剩余的156-12 = 143位来反映内部桶。
OR
创建156位的固定随机排列。