Hash 如何通过算法划分键空间?

Hash 如何通过算法划分键空间?,hash,data-partitioning,Hash,Data Partitioning,这与一致性散列有关,虽然我在概念上理解我需要做什么,但我很难将其转换为代码 我试图将给定的键空间(比如128位)划分为大小相等的分区。我想要每个分区的上限(最高键) 基本上,我该如何完成这项工作 #define KEYSPACE_BYTE_SIZE 16 #define KEYSPACE_BIT_SIZE (KEYSPACE_BYTE_SIZE * 8) typedef struct _key { char byte[KEYSPACE_BYTE_SIZE]; } key; k

这与一致性散列有关,虽然我在概念上理解我需要做什么,但我很难将其转换为代码

我试图将给定的键空间(比如128位)划分为大小相等的分区。我想要每个分区的上限(最高键)

基本上,我该如何完成这项工作

#define KEYSPACE_BYTE_SIZE  16
#define KEYSPACE_BIT_SIZE   (KEYSPACE_BYTE_SIZE * 8)

typedef struct _key
{ 
    char byte[KEYSPACE_BYTE_SIZE];
} key;

key * partition_keyspace( int num_partitions )
{
    key * partitions = malloc( sizeof(key) * num_partitions );

    // ...

}
编辑:

我想另一种说法是:

for (i = 0; i < num_partitions; i++)
{
    partitions[i] = ((2 ^ KEYSPACE_BIT_SIZE) / num_partitions) * i;
}
for(i=0;i
当然,问题是2^128是一个非常大的数字,不能包含在C中的任何一个整数变量中,用它来进行计算(因此是char[16]结构)

我真的不想为此使用大量库(或任何库)

编辑:

虽然,实际上我要找的数字是:

for (i = 0; i < num_partitions; i++)
{
    partitions[i] = (((2 ^ KEYSPACE_BIT_SIZE) / num_partitions) * (i + 1)) - 1;
}
for(i=0;i
我不确定我是否理解您问题的背景-我没有研究一致性哈希


这个问题几乎相当于“我如何在没有排序的情况下进行排序”

另一种方法可能是这样做:

iter = seed() #initialize to the bottom of the hash keys
for(i = 0 to partitionbound)
{
   iter = nextIter(iter);
}
这是线性时间。然而,它不需要密钥空间的先验知识,只需要nextIter遵守一些顺序

如果您正在分区[0,2^128]->{values},例如,您正在执行一些分布式计算或其他操作,那么您的运气会好得多,因为整数结构良好

我建议在一个结构中使用4个32位整数,然后编写自己的bigint例程来解决需要解决的问题

如果你有自由不使用C++,普通LISP内置了BIGNIts。我觉得这很方便


如果你有代表性的钥匙

但是,当在某个空间a中寻找一些大小相等的k个分区(包含n个元素)时,我会这样处理问题:

if( n % k)
{
   return "not equal-sized partition!"
}
//could be forking/threading, whatever.
for(int i = 0; i < n; i+=k)
{
   process(i, i+k-1);
}


process(bottom, top)
{
   sort(a[bottom], a[top]);
   return a[top]; //you'll have to figure out where to dump the results.
}
if(n%k)
{
返回“大小不相等的分区!”
}
//可能是分叉/穿线之类的。
对于(int i=0;i
任何特定分区中的最高密钥显然由所有
1
-位组成。如果您的键具有较低的
n
位,分区ID具有较高的
m
位,那么您只需运行
m
-位计数器,并将其与
n
位计数器连接。
为了举例说明,假设一个8位键空间,上面2位用于分区(因此
num_partitions=2^2=4
,下面6位用于键)。每个分区中的最高键将是以下四个:

00 111111
01 111111
10 111111
11 111111
要生成它们,您只需执行以下操作:

for (int i = 0; i < num_partitions; i++)
    highest_key = (i << 6) | 0x3f // where 6 is key_bits and 0x3f is six ones.
for(inti=0;ihighest_key=(i根据tzaman的答案,这是我的解决方案。它最多允许255个分区(虽然这可以更改)。它不需要2个分区的幂次幂次函数……它只会让最后一个分区占用剩下的任何分区

如果您看到任何bug,请告诉我…:)

key*partition\u键空间(无符号int-num\u分区)
{
断言(num_分区>0);
断言(num_分区<0xFF);
key*partitions=(key*)malloc(sizeof(key)*num_分区);
//满满当当
memset(分区,0xFF,sizeof(键)*num_分区);
//计算1需要填充顶部字节的多少位
无符号字符填充位=0;

while(num_分区>(1)空格不在你可以操作的数组或项目列表中。我只需要知道分区。这有点像是说,如果你有从AAAA到ZZZZ的所有四个字母单词,将它们分成10个相等的分区,并告诉我每个分区中的最后一个单词。现在对字节而不是字母和键空间进行此操作r“word”而不是四个。@pbhogan:(1)你可以根据给定的键计算任意值吗?(2)我假设你可以对键进行排序?有太多的键生成它们,然后对它们进行排序。这不是对一组键的操作,而是对完整的键空间(所有可能的键)的操作。对于128位键空间,我们讨论的是2^128个可能的键…我只希望n个分区中的最后一个可能的键。@pbhogan:我现在更明白了-您试图寻址的元素在技术上不可直接寻址。:)对。:)这是可行的(请参阅我的编辑)使用诸如gmplib之类的bignum库,但我相信有一种更简单的方法可以做到这一点。谢谢!这是我需要的关键。:)
key * partition_keyspace( unsigned int num_partitions )
{
    assert( num_partitions > 0 );
    assert( num_partitions < 0xFF );

    key * partitions = (key *) malloc( sizeof(key) * num_partitions );

    // fill every bit
    memset( partitions, 0xFF, sizeof(key) * num_partitions );

    // calculate how many bits of the top byte needs to be filled by 1's
    unsigned char fill_bits = 0;
    while (num_partitions > (1 << fill_bits)) fill_bits++;
    fill_bits = 8 - fill_bits;

    // fill the top byte with the base number of 1's
    unsigned char fill_part = 0;
    for (unsigned int i = 0; i < fill_bits; i++) fill_part |= 1 << i;

    // last partition takes up whatever remains, so don't process it (hence the -1)
    for (unsigned char i = 0; i < num_partitions - 1; i++)
    {
        partitions[i].byte[0] = fill_part | (i << fill_bits);
    }

    return partitions;
}