有很多UUID有128位,我想将每个UUID设置为一个整数,并在bitset的每个位置标记它。但似乎128位太长了。
如何实现此功能并且没有碰撞?
答案 0 :(得分:2)
通过使用bitset,你需要2 ^ 128,大约是3.4 x 10 ^ 38位。
你想要的东西会花费你更少的记忆,这是可能的。但是如果你想让它完全没有碰撞,那就不可能了,只需要用鸽子洞原理。
但是为什么你希望它成为"没有碰撞"?例如,如果您要使用HashMap
,则相对正常的散列函数,以及将HashMap预初始化为预期大小将为您节省大量冲突。即使有一些碰撞,我也不认为它会对性能产生很大的影响(除非散列方法真的很糟糕)。
如果您的"添加到bitset"是显式的(因此您不需要确定UUID是否已经在位集中):
假设您需要存储100,000,000个设备的状态,则至少需要100,000,000个位。
通过使用合理的散列算法,组成一个27位散列,散列将确定用于存储状态的位。因此,您需要一个2 ^ 27 = 134,217,728位〜= 17MB的位图。
有2 BitSet
这样大小(花费大约34MB),一个用于保持状态,一个用于保持"位的可用性"。
额外Map<UUID, Integer>
作为&#34;特殊设备位&#34;
对于新的UUID,计算27位散列。如果结果值未在&#34; bitAvailabilityBitset&#34;中被占用,请将其打开。
对于新的UUID,如果哈希结果在&#34; bitAvailabilityBitSet&#34;中被占用,找到下一个未占用位的索引,在&#34; bitAvailabilityBitSet&#34;中打开它,并添加UUID +索引对&#34;特殊设备位&#34;地图。
在查找/更新时反向执行操作:首先检查UUID是否在&#34;异常设备位&#34; map,如果是这样,请使用map中的索引进行查找。如果不是,只需将27位散列计算为要查找的索引
给定一个相对较好的散列算法,碰撞不应该是频繁的,因此,额外的开销和#34;异常的设备位&#34;地图不应该很大。您可以进一步调整位集的大小以权衡大小以减少冲突