diff options
-rw-r--r-- | changelog.md | 2 | ||||
-rw-r--r-- | lib/pure/oids.nim | 39 | ||||
-rw-r--r-- | tests/stdlib/toids.nim | 11 |
3 files changed, 26 insertions, 26 deletions
diff --git a/changelog.md b/changelog.md index d70a4367d..8b9676a3a 100644 --- a/changelog.md +++ b/changelog.md @@ -65,6 +65,8 @@ - `strutils.find` now uses and defaults to `last = -1` for whole string searches, making limiting it to just the first char (`last = 0`) valid. - `random.rand` now works with `Ordinal`s. +- `std/oids` now uses `int64` to store time internally (before it was int32), the length of + the string form of `Oid` changes from 24 to 32. [//]: # "Additions:" - Added ISO 8601 week date utilities in `times`: diff --git a/lib/pure/oids.nim b/lib/pure/oids.nim index 776c046b1..43eadad27 100644 --- a/lib/pure/oids.nim +++ b/lib/pure/oids.nim @@ -9,8 +9,7 @@ ## Nim OID support. An OID is a global ID that consists of a timestamp, ## a unique counter and a random value. This combination should suffice to -## produce a globally distributed unique ID. This implementation was extracted -## from the MongoDB interface and is thus binary compatible with a MongoDB OID. +## produce a globally distributed unique ID. ## ## This implementation calls `initRand()` for the first call of ## `genOid`. @@ -20,7 +19,7 @@ from std/private/decode_helpers import handleHexChar type Oid* = object ## An OID. - time: int32 + time: int64 fuzz: int32 count: int32 @@ -44,37 +43,27 @@ proc parseOid*(str: cstring): Oid = ## Parses an OID. var bytes = cast[cstring](addr(result.time)) var i = 0 - while i < 12: + while i < 16: bytes[i] = chr((hexbyte(str[2 * i]) shl 4) or hexbyte(str[2 * i + 1])) inc(i) -template toStringImpl[T: string | cstring](result: var T, oid: Oid) = - ## Stringifies `oid`. +proc `$`*(oid: Oid): string = + ## Converts an OID to a string. const hex = "0123456789abcdef" - const N = 24 - when T is string: - result.setLen N + result.setLen 32 var o = oid var bytes = cast[cstring](addr(o)) var i = 0 - while i < 12: + while i < 16: let b = bytes[i].ord result[2 * i] = hex[(b and 0xF0) shr 4] result[2 * i + 1] = hex[b and 0xF] inc(i) - when T is cstring: - result[N] = '\0' - - -proc `$`*(oid: Oid): string = - ## Converts an OID to a string. - toStringImpl(result, oid) - let - t = getTime().toUnix.int32 + t = getTime().toUnix var seed = initRand(t) @@ -84,24 +73,24 @@ let fuzz = cast[int32](seed.rand(high(int))) template genOid(result: var Oid, incr: var int, fuzz: int32) = - var time = getTime().toUnix.int32 + var time = getTime().toUnix var i = cast[int32](atomicInc(incr)) - bigEndian32(addr result.time, addr(time)) + bigEndian64(addr result.time, addr(time)) result.fuzz = fuzz bigEndian32(addr result.count, addr(i)) proc genOid*(): Oid = ## Generates a new OID. runnableExamples: - doAssert ($genOid()).len == 24 + doAssert ($genOid()).len == 32 runnableExamples("-r:off"): - echo $genOid() # for example, "5fc7f546ddbbc84800006aaf" + echo $genOid() # for example, "00000000632c452db08c3d19ee9073e5" genOid(result, incr, fuzz) proc generatedTime*(oid: Oid): Time = ## Returns the generated timestamp of the OID. - var tmp: int32 + var tmp: int64 var dummy = oid.time - bigEndian32(addr(tmp), addr(dummy)) + bigEndian64(addr(tmp), addr(dummy)) result = fromUnix(tmp) diff --git a/tests/stdlib/toids.nim b/tests/stdlib/toids.nim index f162dbe57..72900d1ef 100644 --- a/tests/stdlib/toids.nim +++ b/tests/stdlib/toids.nim @@ -1,6 +1,15 @@ +discard """ + matrix: "--mm:refc; --mm:orc" +""" + import std/oids block: # genOid let x = genOid() - doAssert ($x).len == 24 + doAssert ($x).len == 32 + +block: + let x = genOid() + let y = parseOid(cstring($x)) + doAssert x == y |