Skip to content

Instantly share code, notes, and snippets.

@draganjovanovic1
Last active March 11, 2019 17:55
Show Gist options
  • Save draganjovanovic1/be2d6d7a6397a31aef0ba4907d38f4f9 to your computer and use it in GitHub Desktop.
Save draganjovanovic1/be2d6d7a6397a31aef0ba4907d38f4f9 to your computer and use it in GitHub Desktop.
Simple unique id generator
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