Skip to content

Commit 7b7592d

Browse files
committed
Token: add constructor and normalization
`i64::MIN` turns out to be an invalid value for a token: https://github.com/scylladb/scylladb/blob/4be70bfc2bc7f133cab492b4aac7bab9c790a48c/dht/token.hh#L32 Hashing algorithm should change `i64::MIN` result to `i64::MAX`. In order to have this check in one place and make sure we always perform it I made `value` field of `Token` non-public and created constructor and getter for it.
1 parent cf0b1cd commit 7b7592d

File tree

12 files changed

+154
-142
lines changed

12 files changed

+154
-142
lines changed

examples/compare-tokens.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,13 @@ async fn main() -> Result<()> {
3333
)
3434
.await?;
3535

36-
let t = prepared.calculate_token(&(pk,))?.unwrap().value;
36+
let t = prepared.calculate_token(&(pk,))?.unwrap().value();
3737

3838
println!(
3939
"Token endpoints for query: {:?}",
4040
session
4141
.get_cluster_data()
42-
.get_token_endpoints("examples_ks", Token { value: t })
42+
.get_token_endpoints("examples_ks", Token::new(t))
4343
.iter()
4444
.map(|(node, _shard)| node.address)
4545
.collect::<Vec<NodeAddr>>()

scylla/src/routing.rs

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,42 @@ use std::num::NonZeroU16;
55
use thiserror::Error;
66

77
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug)]
8+
9+
/// Token is a result of computing a hash of a primary key
10+
///
11+
/// It is basically an i64 with one caveat: i64::MIN is not
12+
/// a valid token. It is used to represent infinity.
13+
/// For this reason tokens are normalized - i64::MIN
14+
/// is replaced with i64::MAX. See this fragment of
15+
/// Scylla code for more information:
16+
/// <https://github.com/scylladb/scylladb/blob/4be70bfc2bc7f133cab492b4aac7bab9c790a48c/dht/token.hh#L32>
17+
///
18+
/// This struct is a wrapper over i64 that performs this normalization
19+
/// when initialized using `new()` method.
820
pub struct Token {
9-
pub value: i64,
21+
value: i64,
22+
}
23+
24+
impl Token {
25+
/// Creates a new token with given value, normalizing the value if necessary
26+
#[inline]
27+
pub fn new(value: i64) -> Self {
28+
Self {
29+
value: if value == i64::MIN { i64::MAX } else { value },
30+
}
31+
}
32+
33+
/// Invalid Token - contains i64::MIN as value.
34+
///
35+
/// This is (currently) only required by CDCPartitioner.
36+
/// See the following comment:
37+
/// https://github.com/scylladb/scylla-rust-driver/blob/049dc3546d24e45106fed0fdb985ec2511ab5192/scylla/src/transport/partitioner.rs#L312-L322
38+
pub(crate) const INVALID: Self = Token { value: i64::MIN };
39+
40+
#[inline]
41+
pub fn value(&self) -> i64 {
42+
self.value
43+
}
1044
}
1145

1246
pub type Shard = u32;

0 commit comments

Comments
 (0)