Skip to content

Commit

Permalink
bug-fix: fixes issue #3 regarding timestamps
Browse files Browse the repository at this point in the history
  • Loading branch information
marcoonroad committed Apr 6, 2018
1 parent 7e74a2f commit 0c60003
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 25 deletions.
61 changes: 39 additions & 22 deletions lib/cuid.ml
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,43 @@ let alphabet = [
"n"; "o"; "p"; "q"; "r"; "s"; "t"; "u"; "v"; "w"; "x"; "y"; "z"
]

let floor_to_int number =
number
|> Core.Float.round_down
|> int_of_float

let rec loop result number =
if number <= 0 then result else
let index = number mod 36 in
let number' = number / 36 in
let digit = List.nth alphabet index in
if number <= 0. then result else
let index = Core.Float.mod_float number 36. in
let number' = Core.Float.(number / 36.) in
let digit = List.nth alphabet (floor_to_int index) in
let result' = digit ^ result in
loop result' number'

let base36 number =
let number' = abs number in
if number' < 36 then
List.nth alphabet number'
let number' = Core.Float.abs number in
if Core.Float.(number' < 36.) then
List.nth alphabet (floor_to_int number')
else
loop "" number'

let adjust8 text =
let length = String.length text in
try
let buffer = String.make (8 - length) '0' in
buffer ^ text
with _ -> Core.String.sub text ~pos:(length - 8) ~len:8
let adjust fill text =
let length = String.length text in
let size = max 0 (fill - length) in
let buffer = String.make size '0' in
buffer ^ text

let padding fill count text =
let adjusted = adjust fill text in
let length = Core.String.length adjusted in
let offset = length - count in
Core.String.sub adjusted ~pos:offset ~len:count

let call lambda = lambda ( )
let padding4 text = Core.String.sub text ~pos:4 ~len:4
let digest text = Digest.to_hex (Digest.string text)
let padding4 = padding 8 4
let padding8 = padding 8 8

let call lambda = lambda ( )
let digest text = Digest.to_hex (Digest.string text)

let sum text =
let number = text
Expand All @@ -43,18 +55,17 @@ let sum text =

let timestamp ( ) =
( )
|> Unix.gettimeofday
|> int_of_float
|> Unix.time
|> base36
|> adjust8
|> padding8

let counter ( ) =
state := (if !state < maximum then !state else 0);
incr state;
!state
|> pred
|> float_of_int
|> base36
|> adjust8
|> padding4

let fingerprint =
Expand All @@ -63,17 +74,23 @@ let fingerprint =
|> digest
|> sum
in (number + Unix.getpid ( ))
|> float_of_int
|> base36
|> adjust8
|> padding4

let random ( ) =
maximum
|> Core.Random.int
|> float_of_int
|> base36
|> adjust8
|> padding4

let __fields ( ) =
(call timestamp),
(call counter),
fingerprint,
(call random ^ call random)

let generate ( ) =
prefix ^
(call timestamp) ^ (call counter) ^
Expand Down
1 change: 1 addition & 0 deletions lib/cuid.mli
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
val __fields : unit -> string * string * string * string
val generate : unit -> string
12 changes: 10 additions & 2 deletions lib_test/cuids.ml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ open Test_utils
let __length_case ( ) =
let cuid = Cuid.generate ( ) in
let length = String.length cuid in
check int "cuid length must be 25" length 25
check int "cuid length must be 25" length 25;
let (timestamp, counter, fingerprint, random) = Cuid.__fields ( ) in
check int "timestamp block length must be 8" (String.length timestamp) 8;
check int "counter block length must be 4" (String.length counter) 4;
check int "fingerprint block length must be 4" (String.length fingerprint) 4;
check int "random block length must be 8" (String.length random) 8

let __base36_case ( ) =
let cuid = Cuid.generate ( ) in
Expand All @@ -13,7 +18,10 @@ let __base36_case ( ) =
check bool "cuid must contain valid base36 chars" (is_base36 cuid) true

let __collision_case ( ) =
check bool "cuid must not collide" (does_collide ( )) false
let first = Cuid.generate ( ) in
check bool "cuid must not collide" (does_collide ( )) false;
let last = Cuid.generate ( ) in
check bool "cuid must be monotonically increasing" (first < last) true

let suite = [
"length", `Quick, __length_case;
Expand Down
2 changes: 1 addition & 1 deletion lib_test/test_utils.ml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ let is_base36 text =

let does_collide ( ) =
let collision = ref false in
let iterations = 20000000 in
let iterations = 200000 in
let cuids = Hashtbl.create iterations in
let rec loop index =
if index > iterations then ( ) else (
Expand Down

0 comments on commit 0c60003

Please sign in to comment.