如何将UUID空间划分为N个相等大小的分区?

时间:2018-06-27 19:45:06

标签: math hex uuid partitioning

以十六进制表示形式的UUID:“ 123e4567-e89b-12d3-a456-426655440000”

我有很多这样的UUID,我想将它们分成N个存储桶,其中N是我的选择,我想生成这些存储桶的边界。

我可以用这些界限轻松地创建16个存储桶:

00000000-0000-0000-0000-000000000000
10000000-0000-0000-0000-000000000000
20000000-0000-0000-0000-000000000000
30000000-0000-0000-0000-000000000000
...
e0000000-0000-0000-0000-000000000000
f0000000-0000-0000-0000-000000000000
ffffffff-ffff-ffff-ffff-ffffffffffff

只需遍历第一个十六进制数字的选项即可。

假设我想要50个相等大小的存储桶(就每个存储桶中包含的UUID可能性而言相等),2000个存储桶或N个存储桶。

我如何根据N生成边界?

2 个答案:

答案 0 :(得分:1)

您上面的UUID的长度为32个十六进制数字。因此,这意味着您有16 ^ 32≈3.4e38个可能的UUID。一个简单的解决方案是使用一个大的int库(或您自己的方法)将这些非常大的值存储为实际数字。然后,您可以将可能的UUID的数量除以N(称为值k),从而得到值为0,k,2 * k,...(N-1)* k,UMAX的存储段边界。

如果N不划分可能的UUID的数量,则会出现问题。显然,并非每个存储桶都具有相同数量的UUID,但是在这种情况下,它们甚至不会均匀分布。例如,如果可能的UUID数为32,而您想要7个存储桶,则k为4,因此您将拥有大小为4、4、4、4、4、4和4的存储桶。这可能是“理想。要解决此问题,您可以将存储桶范围设置为0,(1 * UMAX)/ N,(2 * UMAX)/ N,...(((N-1)* UMAX)/ N,UMAX)。然后,在上述不方便的情况下,您最终将以0、4、9、13、18、22、27、32的范围为界-得出的存储桶大小为4、5、4、5、4、5、5。

您可能需要一个大的int库或一些其他方法来存储大整数才能使用此方法。为了比较,在某些情况下,C ++中的long long最多只能存储2 ^ 64≈1.8e19。

答案 1 :(得分:0)

如果N是2的幂,那么解决方案是显而易见的:您可以在问题的16个存储区之间划分位边界。

如果N不是2的幂,则这些桶在数学上不能完全相等。因此,问题就变成了您以效率的名义容忍的不平等程度。

只要N <2 ^ 24左右,最简单的事情就是将基于前32位的UUID分配到大小为2 ^ 32 / N的N个存储桶中。对于大多数应用程序来说,该速度应该足够快且足够相等,并且如果N需要大于允许的范围,则可以以较小的代价轻松地将位加倍。