@@ -129,6 +129,89 @@ module RBS
129129 #
130130 def uuid : () -> String
131131
132+ # <!--
133+ # rdoc-file=lib/random/formatter.rb
134+ # - uuid_v4()
135+ # -->
136+ #
137+ %a{annotate:rdoc:copy:Random::Formatter#uuid_v4}
138+ alias uuid_v4 uuid
139+
140+ # <!--
141+ # rdoc-file=lib/random/formatter.rb
142+ # - uuid_v7(extra_timestamp_bits: 0)
143+ # -->
144+ # Generate a random v7 UUID (Universally Unique IDentifier).
145+ #
146+ # require 'random/formatter'
147+ #
148+ # Random.uuid_v7 # => "0188d4c3-1311-7f96-85c7-242a7aa58f1e"
149+ # Random.uuid_v7 # => "0188d4c3-16fe-744f-86af-38fa04c62bb5"
150+ # Random.uuid_v7 # => "0188d4c3-1af8-764f-b049-c204ce0afa23"
151+ # Random.uuid_v7 # => "0188d4c3-1e74-7085-b14f-ef6415dc6f31"
152+ # # |<--sorted-->| |<----- random ---->|
153+ #
154+ # # or
155+ # prng = Random.new
156+ # prng.uuid_v7 # => "0188ca51-5e72-7950-a11d-def7ff977c98"
157+ #
158+ # The version 7 UUID starts with the least significant 48 bits of a 64 bit Unix
159+ # timestamp (milliseconds since the epoch) and fills the remaining bits with
160+ # random data, excluding the version and variant bits.
161+ #
162+ # This allows version 7 UUIDs to be sorted by creation time. Time ordered UUIDs
163+ # can be used for better database index locality of newly inserted records,
164+ # which may have a significant performance benefit compared to random data
165+ # inserts.
166+ #
167+ # The result contains 74 random bits (9.25 random bytes).
168+ #
169+ # Note that this method cannot be made reproducible because its output includes
170+ # not only random bits but also timestamp.
171+ #
172+ # See [RFC9562](https://www.rfc-editor.org/rfc/rfc9562) for details of UUIDv7.
173+ #
174+ # #### Monotonicity
175+ #
176+ # UUIDv7 has millisecond precision by default, so multiple UUIDs created within
177+ # the same millisecond are not issued in monotonically increasing order. To
178+ # create UUIDs that are time-ordered with sub-millisecond precision, up to 12
179+ # bits of additional timestamp may added with `extra_timestamp_bits`. The extra
180+ # timestamp precision comes at the expense of random bits. Setting
181+ # `extra_timestamp_bits: 12` provides ~244ns of precision, but only 62 random
182+ # bits (7.75 random bytes).
183+ #
184+ # prng = Random.new
185+ # Array.new(4) { prng.uuid_v7(extra_timestamp_bits: 12) }
186+ # # =>
187+ # ["0188d4c7-13da-74f9-8b53-22a786ffdd5a",
188+ # "0188d4c7-13da-753b-83a5-7fb9b2afaeea",
189+ # "0188d4c7-13da-754a-88ea-ac0baeedd8db",
190+ # "0188d4c7-13da-7557-83e1-7cad9cda0d8d"]
191+ # # |<--- sorted --->| |<-- random --->|
192+ #
193+ # Array.new(4) { prng.uuid_v7(extra_timestamp_bits: 8) }
194+ # # =>
195+ # ["0188d4c7-3333-7a95-850a-de6edb858f7e",
196+ # "0188d4c7-3333-7ae8-842e-bc3a8b7d0cf9", # <- out of order
197+ # "0188d4c7-3333-7ae2-995a-9f135dc44ead", # <- out of order
198+ # "0188d4c7-3333-7af9-87c3-8f612edac82e"]
199+ # # |<--- sorted -->||<---- random --->|
200+ #
201+ # Any rollbacks of the system clock will break monotonicity. UUIDv7 is based on
202+ # UTC, which excludes leap seconds and can rollback the clock. To avoid this,
203+ # the system clock can synchronize with an NTP server configured to use a "leap
204+ # smear" approach. NTP or PTP will also be needed to synchronize across
205+ # distributed nodes.
206+ #
207+ # Counters and other mechanisms for stronger guarantees of monotonicity are not
208+ # implemented. Applications with stricter requirements should follow [Section
209+ # 6.2](https://www.rfc-editor.org/rfc/rfc9562.html#name-monotonicity-and-counter
210+ # s) of the specification.
211+ #
212+ %a{annotate:rdoc:copy:Random::Formatter#uuid_v7}
213+ def uuid_v7 : (?extra_timestamp_bits: Integer) -> String
214+
132215 # <!--
133216 # rdoc-file=lib/random/formatter.rb
134217 # - alphanumeric(n = nil, chars: ALPHANUMERIC)
@@ -157,6 +240,35 @@ module RBS
157240 # prng.alphanumeric(10, chars: [*"!".."/"]) #=> ",.,++%/''."
158241 #
159242 def alphanumeric : (?Numeric?, ?chars: Array[String]) -> String
243+
244+ # <!--
245+ # rdoc-file=lib/random/formatter.rb
246+ # - gen_random(n)
247+ # -->
248+ # Internal interface to Random; Generate random data *n* bytes.
249+ #
250+ %a{annotate:rdoc:copy:Random::Formatter#gen_random}
251+ private def gen_random : (Integer n) -> String
252+
253+ # <!--
254+ # rdoc-file=lib/random/formatter.rb
255+ # - choose(source, n)
256+ # -->
257+ # Generate a string that randomly draws from a source array of characters.
258+ #
259+ # The argument *source* specifies the array of characters from which to generate
260+ # the string. The argument *n* specifies the length, in characters, of the
261+ # string to be generated.
262+ #
263+ # The result may contain whatever characters are in the source array.
264+ #
265+ # require 'random/formatter'
266+ #
267+ # prng.choose([*'l'..'r'], 16) #=> "lmrqpoonmmlqlron"
268+ # prng.choose([*'0'..'9'], 5) #=> "27309"
269+ #
270+ %a{annotate:rdoc:copy:Random::Formatter#choose}
271+ private def choose : (Array[String] source, Integer n) -> String
160272 end
161273 end
162274end
0 commit comments