1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
use thread_rng;
use RngCore;
use RefCell;
use ExclusiveId;
use Id;
/// Generator for Fast Unsafe Compressible IDs (FUCIDs).
///
/// Each source holds a random salt and an incrementing counter. Sequential ids
/// from the same source differ by only a few bits, enabling efficient
/// compression while remaining globally unique with high probability.
thread_local!;
/// # Fast Unsafe Compressible IDs (FUCIDs)
///
/// FUCIDs are 128-bit identifiers generated by XORing a random `salt`
/// with an incrementing counter. Each source (e.g., each thread) produces a unique
/// sequence of identifiers with high global and low local entropy.
/// This ensures global uniqueness while allowing for efficient compression and high data locality.
///
/// ## Collision Resistance
///
/// - Within a single source, the exhaustive traversal of the 128-bit space
/// minimizes the risk of collisions.
/// - Across different sources, the uniqueness of the `salt` ensures global uniqueness
/// without requiring coordination.
///
/// ## Considerations
///
/// - Due to low entropy between sequential IDs from the same source,
/// FUCIDs may be more vulnerable to hardware errors (e.g., bit-flips).
/// - Despite having some local randomness, FUCIDs are relatively easy to predict
/// or guess on a per-source basis due to their low local entropy.
///
/// ## Usage Examples
///
/// Each thread has a thread-local `FUCIDsource` that is automatically used when
/// generating IDs via the `fucid` function. This approach is simple and efficient
/// for most use cases.
///
/// ```rust
/// use triblespace_core::id::fucid;
///
/// let id1 = fucid();
/// let id2 = fucid();
/// assert_ne!(id1, id2);
/// ```
///
/// For scenarios where more explicit control is desired, such as creating multiple
/// independent sequences or avoiding thread-local storage, a dedicated `FUCIDsource`
/// can be instantiated and used directly.
///
/// ```rust
/// use triblespace_core::id::FUCIDsource;
///
/// let mut source = FUCIDsource::new();
/// let id1 = source.mint();
/// let id2 = source.mint();
/// assert_ne!(id1, id2);
/// ```
///
/// Note that creating a new `FUCIDsource` for each ID is equivalent to the
/// [RNGID](crate::id::rngid::rngid) scheme.