fix: no more id collisions
This commit is contained in:
parent
71d017693c
commit
0b3573a513
11 changed files with 151 additions and 120 deletions
|
@ -1,51 +1,29 @@
|
|||
//! Almost Snowflake
|
||||
//!
|
||||
//! Random IDs which include timestamp information (like Twitter Snowflakes)
|
||||
//!
|
||||
//! IDs are generated with 41 bits of an epoch timestamp, 10 bits of a machine/server ID, and 12 bits of randomly generated numbers.
|
||||
//!
|
||||
//! ```
|
||||
//! tttttttttttttttttttttttttttttttttttttttttiiiiiiiiiirrrrrrrrrrrr...
|
||||
//! Timestamp ID Seed
|
||||
//! ```
|
||||
use crate::epoch_timestamp;
|
||||
use std::time::{UNIX_EPOCH, Duration};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use snowflaked::{Builder, Generator};
|
||||
|
||||
use num_bigint::BigInt;
|
||||
use rand::Rng;
|
||||
|
||||
static SEED_LEN: usize = 12;
|
||||
// static ID_LEN: usize = 10;
|
||||
pub const EPOCH_2024: u64 = 1704067200000;
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct AlmostSnowflake(String);
|
||||
pub struct Snowflake(String);
|
||||
|
||||
pub fn bigint(input: usize) -> BigInt {
|
||||
BigInt::from(input)
|
||||
}
|
||||
impl Snowflake {
|
||||
pub fn builder() -> Builder {
|
||||
Builder::new().epoch(UNIX_EPOCH + Duration::from_millis(EPOCH_2024))
|
||||
}
|
||||
|
||||
impl AlmostSnowflake {
|
||||
/// Create a new [`AlmostSnowflake`]
|
||||
pub fn new(server_id: usize) -> Self {
|
||||
// generate random bytes
|
||||
let mut bytes = String::new();
|
||||
|
||||
let mut rng = rand::rng();
|
||||
for _ in 1..=SEED_LEN {
|
||||
bytes.push_str(&rng.random_range(0..10).to_string())
|
||||
}
|
||||
|
||||
// build id
|
||||
let mut id = bigint(epoch_timestamp(2024) as usize) << 22_u128;
|
||||
id |= bigint((server_id % 1024) << 12);
|
||||
id |= bigint((bytes.parse::<usize>().unwrap() + 1) % 4096);
|
||||
|
||||
// return
|
||||
Self(id.to_string())
|
||||
pub fn new() -> Self {
|
||||
Self(
|
||||
Self::builder()
|
||||
.build::<Generator>()
|
||||
.generate::<u64>()
|
||||
.to_string(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for AlmostSnowflake {
|
||||
impl std::fmt::Display for Snowflake {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", self.0)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue