/// <summary> /// Initializes a new instance of the <see cref="MonotonicUlidRng"/> class. /// </summary> /// <param name="rng">The <see cref="IUlidRng"/> to get the random numbers from.</param> /// <param name="lastValue">The last value to 'continue from'; use <see langword="null"/> for defaults.</param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="rng"/> is null.</exception> public MonotonicUlidRng(IUlidRng rng, Ulid?lastValue = null) { _rng = rng ?? throw new ArgumentNullException(nameof(rng)); _lastvalue = lastValue == null ? new byte[RANDLEN] : lastValue.Value.Random; _lastgen = Ulid.ToUnixTimeMilliseconds(lastValue == null ? Ulid.EPOCH : lastValue.Value.Time); }
/// <summary> /// Creates and returns a new <see cref="Ulid"/> based on the specified time and using the specified RNG. /// </summary> /// <param name="time"> /// The <see cref="DateTimeOffset"/> to use for the time-part of the <see cref="Ulid"/>. /// </param> /// <param name="rng">The <see cref="IUlidRng"/> to use for random number generation.</param> /// <returns>Returns a new <see cref="Ulid"/>.</returns> /// <exception cref="ArgumentNullException">Thrown when <paramref name="rng"/> is <see langword="null"/>.</exception> public static Ulid NewUlid(DateTimeOffset time, IUlidRng rng) { if (rng == null) { throw new ArgumentNullException(nameof(rng)); } return(new Ulid(time, rng.GetRandomBytes(time))); }
/// <summary> /// Initializes a new instance of the <see cref="MonotonicUlidRng"/> class. /// </summary> /// <param name="rng">The <see cref="IUlidRng"/> to get the random numbers from.</param> /// <param name="maskMsbBits"> /// The number of (most significant) bits to mask out / set to 0 when generating a random value for a given /// timestamp /// </param> /// <param name="lastValue">The last value to 'continue from'; use <see langword="null"/> for defaults.</param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="rng"/> is null.</exception> /// <exception cref="ArgumentOutOfRangeException"> /// Thrown when <paramref name="maskMsbBits"/> is less than 0 or more than 70. /// </exception> public MonotonicUlidRng(IUlidRng rng, int maskMsbBits = DEFAULTMSBMASKBITS, Ulid?lastValue = null) { _rng = rng ?? throw new ArgumentNullException(nameof(rng)); var maskbits = maskMsbBits >= 0 && maskMsbBits <= 80 - DEFAULTMSBMASKBITS ? maskMsbBits : throw new ArgumentOutOfRangeException(nameof(maskMsbBits)); _lastvalue = lastValue == null ? new byte[RANDLEN] : lastValue.Value.Random; _lastgen = Ulid.ToUnixTimeMilliseconds(lastValue == null ? Ulid.EPOCH : lastValue.Value.Time); // Prepare (or 'pre-compute') mask for (var i = 0; i < _mask.Length; i++) { var bits = maskbits > 8 ? 8 : maskbits; // Calculate number of bits to mask from this byte maskbits -= bits; // Decrease number of bits needing to mask total _mask[i] = (byte)((1 << 8 - bits) - 1); } }
/// <summary> /// Creates and returns a new <see cref="Ulid"/> based on the current (UTC) time and using the specified RNG. /// </summary> /// <param name="rng">The <see cref="IUlidRng"/> to use for random number generation.</param> /// <returns>Returns a new <see cref="Ulid"/>.</returns> public static Ulid NewUlid(IUlidRng rng) => NewUlid(DateTimeOffset.UtcNow, rng);
/// <summary> /// Creates and returns a new <see cref="Ulid"/> based on the current (UTC) time and using the specified RNG. /// </summary> /// <param name="rng">The <see cref="IUlidRng"/> to use for random number generation.</param> /// <returns>Returns a new <see cref="Ulid"/>.</returns> public static Ulid NewUlid(IUlidRng rng) { return(NewUlid(DateTimeOffset.UtcNow, rng)); }
/// <summary> /// Creates and returns a new <see cref="Ulid"/> based on the specified time and using the specified RNG. /// </summary> /// <param name="time"> /// The <see cref="DateTimeOffset"/> to use for the time-part of the <see cref="Ulid"/>. /// </param> /// <param name="rng">The <see cref="IUlidRng"/> to use for random number generation.</param> /// <returns>Returns a new <see cref="Ulid"/>.</returns> public static Ulid NewUlid(DateTimeOffset time, IUlidRng rng) { return(new Ulid(time, rng.GetRandomBytes(10))); }
/// <summary> /// Initializes a new instance of the <see cref="MonotonicUlidRng"/> class with a specified /// <see cref="IUlidRng"/> and default number of mask bits. /// </summary> /// <param name="rng">The <see cref="IUlidRng"/> to get the random numbers from.</param> public MonotonicUlidRng(IUlidRng rng) : this(rng, DEFAULTMSBMASKBITS) { }