3

My Cassandra ColumnFamily uses the Murmur3Partitioner, and has a composite partition key. With this partitioner I was trying to create a Token, however it seems this token factory only allows Long values. Is it possible to generate these hashes for something like "token(partition_column1, partition_column2)"?

user3507166
  • 33
  • 1
  • 4

3 Answers3

7

It's supposed to work. In fact, if your partition key is composite, you should be unable to create a token for only a single column. Are you sure that you've defined the composite key properly?

cqlsh:testks> create table t1(k1 int, k2 text, v text, primary key((k1, k2)));
cqlsh:testks> insert into t1(k1, k2, v) values (1, 'key', 'value');
cqlsh:testks> select * from t1;

 k1 | k2  | v
----+-----+-------
  1 | key | value

(1 rows)

cqlsh:testks> select token(k1) from t1;
Bad Request: Invalid number of arguments in call to function token: 2 required but 1 provided
cqlsh:testks> select token(k2) from t1;
Bad Request: Invalid number of arguments in call to function token: 2 required but 1 provided
cqlsh:testks> select token(k1, k2) from t1;

 token(k1, k2)
---------------------
 8064425790465501062

    (1 rows)
Daniel S.
  • 3,494
  • 24
  • 30
  • That's correct, all statements above hold. However, I was looking for means to create such token from the java api, instead of performing queries, i.e. to generate the possible token ranges using org.apache.cassandra.dht.Murmur3Partitioner. – user3507166 Apr 07 '14 at 20:00
  • If you want to create it using Java APIs, you'll have to use the `partitioner.getToken(ByteBuffer)` API. For details, you can start looking at the implementation of CQL `token()` function in https://github.com/apache/cassandra/blob/trunk/src/java/org/apache/cassandra/cql3/functions/TokenFct.java . – Daniel S. Apr 07 '14 at 20:54
1

This is the formula for calculating Hash, I found on Datastax web :

(((2**64 / number_of_tokens) * i) - 2**63) for i in range(number_of_tokens)

This hashing function creates a 64-bit hash value of the partition key

So the Hash can be in range of -2^63 to +2^63-1 (2 to power 63)

Madhur Bhaiya
  • 28,155
  • 10
  • 49
  • 57
Himanshu Singh
  • 199
  • 3
  • 15
0

The Algorithm to compute the token for a composite partition key : Primary_key((text, int)) -> therefore the partition key is a composite_partition_key (text, int).

Example : a row with composite_partition_key ('hello', 1)

Applying the algorithm :

1- lay-out the components of the composite partition key in big-endian (16 bits) presentation :

first_component = 'hello' -> 68 65 6c 6c 6f

sec_component = 1 -> 00 00 00 01

68 65 6c 6c 6f 00 00 00 01

2- add two-bytes length of component before each component

first_component = 'hello', length= 5-> 00 05 68 65 6c 6c 6f

sec_component = 1, therefore length= 4 -> 00 04 00 00 00 01

00 05 68 65 6c 6c 6f 00 04 00 01

3- add zero-value after each component

first_component = 'hello' -> 00 05 68 65 6c 6c 6f 00

sec_component = 1 -> 00 04 00 00 00 01 00

4- result

00 05 68 65 6c 6c 6f 00 00 04 00 00 00 01 00

now pass the result as whatever binary base your murmur3 function understand (make sure it's cassandra variant).

aiomix
  • 11
  • 3