JMAP Registry API implementation - part 2
This commit is contained in:
@@ -9,6 +9,7 @@ use std::{
|
||||
collections::{BTreeMap, HashMap, HashSet},
|
||||
fmt::Debug,
|
||||
hash::Hash,
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
// A hash that can cheekily store small inputs directly without hashing them.
|
||||
@@ -91,6 +92,10 @@ impl CheekyHash {
|
||||
pub fn payload_len(&self) -> u8 {
|
||||
self.0[0]
|
||||
}
|
||||
|
||||
fn as_u128(&self) -> u128 {
|
||||
u128::from_be_bytes(self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<[u8]> for CheekyHash {
|
||||
@@ -99,6 +104,20 @@ impl AsRef<[u8]> for CheekyHash {
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for CheekyHash {
|
||||
type Err = std::num::ParseIntError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
u128::from_str_radix(s, 16).map(|n| CheekyHash(n.to_be_bytes()))
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for CheekyHash {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{:032x}", self.as_u128())
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for CheekyHash {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
let len = self.0[0] as usize;
|
||||
|
||||
@@ -12,7 +12,6 @@ use std::{
|
||||
#[derive(Debug)]
|
||||
pub struct SnowflakeIdGenerator {
|
||||
epoch: SystemTime,
|
||||
node_id: u64,
|
||||
sequence: AtomicU64,
|
||||
}
|
||||
|
||||
@@ -23,7 +22,8 @@ const SEQUENCE_MASK: u64 = (1 << SEQUENCE_LEN) - 1;
|
||||
const NODE_ID_MASK: u64 = (1 << NODE_ID_LEN) - 1;
|
||||
|
||||
const DEFAULT_EPOCH: u64 = 1632280000; // 52 years after UNIX_EPOCH
|
||||
//const DEFAULT_EPOCH_MS: u128 = (DEFAULT_EPOCH as u128) * 1000; // 52 years after UNIX_EPOCH in milliseconds
|
||||
|
||||
static mut NODE_ID: u64 = 1;
|
||||
|
||||
/*
|
||||
|
||||
@@ -35,9 +35,27 @@ ID characteristics:
|
||||
|
||||
*/
|
||||
|
||||
#[inline(always)]
|
||||
fn node_id() -> u64 {
|
||||
unsafe { std::ptr::read_volatile(&raw const NODE_ID) }
|
||||
}
|
||||
|
||||
impl SnowflakeIdGenerator {
|
||||
pub fn new() -> Self {
|
||||
Self::with_node_id(rand::random::<u64>())
|
||||
Self {
|
||||
epoch: SystemTime::UNIX_EPOCH + Duration::from_secs(DEFAULT_EPOCH), // 52 years after UNIX_EPOCH
|
||||
sequence: 0.into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_node_id(set_node_id: u64) {
|
||||
let set_node_id = set_node_id & NODE_ID_MASK;
|
||||
|
||||
if set_node_id != node_id() {
|
||||
unsafe {
|
||||
NODE_ID = set_node_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_duration(period: Duration) -> Option<u64> {
|
||||
@@ -56,8 +74,7 @@ impl SnowflakeIdGenerator {
|
||||
.and_then(|diff| Self::from_duration(Duration::from_secs(diff)))
|
||||
}
|
||||
|
||||
pub fn from_sequence_and_node_id(sequence: u64, node_id: Option<u64>) -> Option<u64> {
|
||||
let node_id = node_id.unwrap_or_else(rand::random::<u64>);
|
||||
pub fn from_sequence_id(sequence: u64) -> Option<u64> {
|
||||
let sequence = sequence & SEQUENCE_MASK;
|
||||
|
||||
(SystemTime::UNIX_EPOCH + Duration::from_secs(DEFAULT_EPOCH))
|
||||
@@ -66,7 +83,7 @@ impl SnowflakeIdGenerator {
|
||||
.map(|elapsed| {
|
||||
((elapsed.as_millis() as u64) << (SEQUENCE_LEN + NODE_ID_LEN))
|
||||
| (sequence << NODE_ID_LEN)
|
||||
| (node_id & NODE_ID_MASK)
|
||||
| node_id()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -74,14 +91,6 @@ impl SnowflakeIdGenerator {
|
||||
(id >> (SEQUENCE_LEN + NODE_ID_LEN)) / 1000 + DEFAULT_EPOCH
|
||||
}
|
||||
|
||||
pub fn with_node_id(node_id: u64) -> Self {
|
||||
Self {
|
||||
epoch: SystemTime::UNIX_EPOCH + Duration::from_secs(DEFAULT_EPOCH), // 52 years after UNIX_EPOCH
|
||||
node_id,
|
||||
sequence: 0.into(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn past_id(&self, period: Duration) -> Option<u64> {
|
||||
self.epoch
|
||||
@@ -104,9 +113,7 @@ impl SnowflakeIdGenerator {
|
||||
.unwrap_or_default() as u64;
|
||||
let sequence = self.sequence.fetch_add(1, Ordering::Relaxed) & SEQUENCE_MASK;
|
||||
|
||||
(elapsed << (SEQUENCE_LEN + NODE_ID_LEN))
|
||||
| (sequence << NODE_ID_LEN)
|
||||
| (self.node_id & NODE_ID_MASK)
|
||||
(elapsed << (SEQUENCE_LEN + NODE_ID_LEN)) | (sequence << NODE_ID_LEN) | node_id()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,7 +127,6 @@ impl Clone for SnowflakeIdGenerator {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
epoch: self.epoch,
|
||||
node_id: self.node_id,
|
||||
sequence: 0.into(),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user