(min, max, callback)
| 209 | // Generates an integer in [min, max) range where min is inclusive and max is |
| 210 | // exclusive. |
| 211 | function randomInt(min, max, callback) { |
| 212 | // Detect optional min syntax |
| 213 | // randomInt(max) |
| 214 | // randomInt(max, callback) |
| 215 | const minNotSpecified = typeof max === 'undefined' || |
| 216 | typeof max === 'function'; |
| 217 | |
| 218 | if (minNotSpecified) { |
| 219 | callback = max; |
| 220 | max = min; |
| 221 | min = 0; |
| 222 | } |
| 223 | |
| 224 | const isSync = typeof callback === 'undefined'; |
| 225 | if (!isSync) { |
| 226 | validateFunction(callback, 'callback'); |
| 227 | } |
| 228 | if (!NumberIsSafeInteger(min)) { |
| 229 | throw new ERR_INVALID_ARG_TYPE('min', 'a safe integer', min); |
| 230 | } |
| 231 | if (!NumberIsSafeInteger(max)) { |
| 232 | throw new ERR_INVALID_ARG_TYPE('max', 'a safe integer', max); |
| 233 | } |
| 234 | if (max <= min) { |
| 235 | throw new ERR_OUT_OF_RANGE( |
| 236 | 'max', `greater than the value of "min" (${min})`, max, |
| 237 | ); |
| 238 | } |
| 239 | |
| 240 | // First we generate a random int between [0..range) |
| 241 | const range = max - min; |
| 242 | |
| 243 | if (!(range <= RAND_MAX)) { |
| 244 | throw new ERR_OUT_OF_RANGE(`max${minNotSpecified ? '' : ' - min'}`, |
| 245 | `<= ${RAND_MAX}`, range); |
| 246 | } |
| 247 | |
| 248 | // For (x % range) to produce an unbiased value greater than or equal to 0 and |
| 249 | // less than range, x must be drawn randomly from the set of integers greater |
| 250 | // than or equal to 0 and less than randLimit. |
| 251 | const randLimit = RAND_MAX - (RAND_MAX % range); |
| 252 | |
| 253 | // If we don't have a callback, or if there is still data in the cache, we can |
| 254 | // do this synchronously, which is super fast. |
| 255 | while (isSync || (randomCacheOffset < randomCache.length)) { |
| 256 | if (randomCacheOffset === randomCache.length) { |
| 257 | // This might block the thread for a bit, but we are in sync mode. |
| 258 | randomFillSync(randomCache); |
| 259 | randomCacheOffset = 0; |
| 260 | } |
| 261 | |
| 262 | const x = randomCache.readUIntBE(randomCacheOffset, 6); |
| 263 | randomCacheOffset += 6; |
| 264 | |
| 265 | if (x < randLimit) { |
| 266 | const n = (x % range) + min; |
| 267 | if (isSync) return n; |
| 268 | process.nextTick(callback, undefined, n); |
no test coverage detected
searching dependent graphs…