Last active
March 11, 2019 17:55
-
-
Save draganjovanovic1/be2d6d7a6397a31aef0ba4907d38f4f9 to your computer and use it in GitHub Desktop.
Simple unique id generator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
open System | |
open System.Threading | |
open System.Text | |
type IdGenerator<'a> private (chars: char seq, getTime: unit -> int64, transform: string -> 'a) = | |
let chars = | |
chars | |
|> Seq.distinct | |
|> Seq.toArray | |
let lastValue = ref (getTime ()) | |
let getValue () = | |
let rec getValue () = | |
let original = lastValue.Value | |
let now = getTime () | |
let newValue = max now (original + 1L) | |
if Interlocked.CompareExchange (lastValue, newValue, original) <> original then | |
getValue () | |
else | |
newValue | |
getValue () | |
let generate () = | |
let generate input = | |
let rec generate (no: int64) (sb: StringBuilder) = | |
let quotient = no / int64 chars.Length | |
let remainder = no % int64 chars.Length | |
sb.Append (chars.[int32 remainder]) |> ignore | |
if quotient > 0L then generate quotient sb | |
let result = StringBuilder () | |
generate input result | |
transform (string result) | |
getValue () | |
|> generate | |
static member OfEpochSeconds<'a> (chars, transform) = | |
let getTime () = DateTimeOffset.UtcNow.ToUnixTimeSeconds () | |
IdGenerator<'a> (chars, getTime, transform) | |
static member OfEpochMilliseconds<'a> (chars, transform) = | |
let getTime () = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds () | |
IdGenerator<'a> (chars, getTime, transform) | |
static member OfTicks<'a> (chars, transform) = | |
let getTime () = DateTimeOffset.UtcNow.Ticks | |
IdGenerator<'a> (chars, getTime, transform) | |
member __.NextId () = generate () |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment