TracingIDFactory
public struct TracingIDFactory
A high-performance unique ID generator optimized for distributed tracing and request tracking.
TracingIDFactory generates unique, monotonically increasing IDs that combine temporal and sequential components for excellent uniqueness guarantees across distributed systems. The factory uses a hybrid approach combining time-based base IDs with sequential counters to ensure both uniqueness and ordering.
Core Design Principles
Hybrid ID Generation
The factory generates IDs using the formula: ID = (timeBasedID × loopCount) + sequentialCounter
- Time-based component: Seconds since start of current year (UTC) - provides temporal ordering
- Sequential component: Incrementing counter that wraps at configurable loop count - ensures uniqueness
- Combined result: Globally unique ID with built-in temporal and sequential properties
Performance Characteristics
- High throughput: Generates millions of IDs per second with minimal overhead
- Memory efficient: Minimal state (3 Int64 values + lock)
- CPU optimized: Simple arithmetic operations, no string formatting or complex calculations
- Lock-free option: Unsafe variants avoid synchronization for maximum performance
Uniqueness Guarantees
- Temporal uniqueness: IDs generated at different times are naturally ordered
- Sequential uniqueness: IDs generated in rapid succession are guaranteed unique
- Cross-instance safety: Different instances initialized at different times generate different ID ranges
- Rollover handling: Sequential counter wraps safely without ID collisions
Usage Examples
// Basic usage with default settings (thread-safe)
var factory = TracingIDFactory()
let id1 = factory.safeNextString() // "1234567890123456789"
let id2 = factory.safeNextUInt64() // 1234567890123456790
// High-performance usage (requires external synchronization)
var factory = TracingIDFactory()
let fastID = factory.unsafeNextInt64() // Maximum performance
// Custom configuration for high-frequency scenarios
var highFreq = TracingIDFactory(loopCount: 1_000_000)
let customID = highFreq.safeNextUInt64()
Thread Safety
- Safe methods: Use internal
os_unfair_lock
for thread safety with minimal overhead - Unsafe methods: No synchronization - caller must ensure thread safety or single-threaded access
- Mixed usage: Safe and unsafe methods can be mixed - each call is independent
Performance Considerations
- Safe vs Unsafe: Unsafe methods are ~10-15% faster, safe methods have negligible lock overhead
- Return type impact: All return types have similar performance (conversion is minimal)
- Initialization cost: One-time UTC calendar calculation - amortized across millions of IDs
- Memory footprint: ~64 bytes total including lock and temporal calculation state
-
Maximum allowed value for sequential counter loop count.
This defines the range of the sequential component before it wraps back to 0. Chosen to balance uniqueness guarantees with performance and overflow prevention.
Usage implications:
- With default: 10 billion unique IDs per time-based ID before sequential wraparound
- Lower values: More frequent wraparound but better cache locality
- Higher values: Longer uniqueness period but higher memory usage for large IDs
Declaration
Swift
public static let maximumLoopCount: Int64
-
Minimum allowed value for sequential counter loop count. Ensures a floor on uniqueness window before wraparound.
Declaration
Swift
public static let minimumLoopCount: Int64
-
Initializes a new TracingIDFactory with configurable sequential counter range.
The initializer performs one-time setup including temporal base ID calculation and loop count validation. The temporal component ensures different instances initialized at different times will generate IDs in different ranges, preventing collisions.
Initialization Process
- Validate loop count: Clamp input to valid range and handle edge cases
- Calculate temporal base: Compute seconds since start of current year (UTC)
- Apply safety limits: Ensure base ID stays within overflow-safe bounds
- Initialize state: Set up sequential counter and synchronization primitives
Performance Impact
- One-time cost: UTC calendar calculations performed only during initialization
- Memory allocation: Minimal - only primitive types and one lock
- Future calls: Initialization cost is amortized across millions of ID generations
Declaration
Swift
public init(loopCount: Int64 = Self.maximumLoopCount)
Parameters
loopCount
Maximum value for the sequential counter before wraparound. Values are automatically clamped to the valid range [1, maximumLoopCount]. Default:
maximumLoopCount
(10 billion) for maximum uniqueness period. -
Generates a thread-safe unique tracing ID as a String.
This method uses internal locking to ensure thread safety, making it suitable for concurrent access across multiple threads. The performance cost is minimal for most use cases.
Note
Thread-safe but slightly slower than unsafe variantDeclaration
Swift
mutating func safeNextString() -> String
Return Value
A unique string representation of the tracing ID
-
Generates a unique tracing ID as a String without thread safety guarantees.
This method provides maximum performance by avoiding synchronization overhead. Use only when you can guarantee single-threaded access or have external synchronization.
Warning
Not thread-safe. Ensure single-threaded access or external synchronizationDeclaration
Swift
mutating func unsafeNextString() -> String
Return Value
A unique string representation of the tracing ID
-
Generates a thread-safe unique tracing ID as an unsigned 64-bit integer.
This method uses internal locking to ensure thread safety. The UInt64 format provides excellent performance for numeric operations and comparisons while maintaining uniqueness.
Note
Thread-safe but slightly slower than unsafe variantDeclaration
Swift
mutating func safeNextUInt64() -> UInt64
Return Value
A unique UInt64 tracing ID
-
Generates a unique tracing ID as an unsigned 64-bit integer without thread safety.
This method provides maximum performance for numeric ID generation by avoiding synchronization overhead. Ideal for high-frequency ID generation in single-threaded contexts.
Warning
Not thread-safe. Ensure single-threaded access or external synchronizationDeclaration
Swift
mutating func unsafeNextUInt64() -> UInt64
Return Value
A unique UInt64 tracing ID
-
Generates a thread-safe unique tracing ID as a signed 64-bit integer.
This method returns the raw signed integer format used internally by the factory. Provides thread safety through internal locking mechanisms.
Note
Thread-safe but slightly slower than unsafe variantDeclaration
Swift
mutating func safeNextInt64() -> Int64
Return Value
A unique Int64 tracing ID (raw internal format)
-
Generates a unique tracing ID as a signed 64-bit integer without thread safety.
This method returns the raw signed integer format with maximum performance. Use when thread safety is not required or is handled externally.
Warning
Not thread-safe. Ensure single-threaded access or external synchronizationDeclaration
Swift
mutating func unsafeNextInt64() -> Int64
Return Value
A unique Int64 tracing ID (raw internal format)