uniquerand

package module
v2.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 10, 2026 License: Apache-2.0 Imports: 2 Imported by: 0

README

uniquerand v2

PkgGoDev Go Report Card Tests Go Coverage

Provides functionality to generate unique random numbers within a specified range, with support for generics, and custom range and step.

Features

  • Generate unique random numbers within a specified range.
  • Generics: Support for any integer type (int, int32, uint64, etc.).
  • Optimized for short ranges.
  • Configure range, step, min, and max.
  • Memory efficient: Uses bitsets to track used numbers.
  • Iterator support (Go 1.23+'s iter.Seq).
  • Common methods:
    • Get: generates a unique random number.
    • Put: reverts the generation of a unique random number, for later generation again.
    • Used: checks whether a number was generated or not.
    • Clear: clears the generator state and memory to reuse it again.
    • Len: returns the number of unique random numbers already generated.
    • Cap: returns the total number of unique random numbers that could be generated.

Getting Started

Prerequisites
  • go1.23 or higher.
Installation
go get github.com/asmsh/uniquerand/v2

Usage

package main

import (
	"fmt"
	
	"github.com/asmsh/uniquerand/v2"
)

func main() {
	// Create a generator for unique int32 values in range [0, 20) with step of 2.
	rn := uniquerand.NewN(uniquerand.Config[int32]{
		Max:  20,
		Step: 2,
	})

	// Get all possible values via Get.
	for v, ok := rn.Get(); ok; v, ok = rn.Get() {
		fmt.Println("Unique number:", v)

		// Put the values back, to make them available for later...
		rn.Put(v)
	}
	
	// Or, using iterators.
	for v := range rn.Values() {
		fmt.Println("Iterator value:", v)
	}
}

Limitations

Memory Usage

This library is designed for generation of unique numbers within a specific range, and it uses in-memory bitsets to track the used numbers. This means the memory usage is directly proportional to the size of the range: (Max - Min) / Step.

Performance

Some benchmarks:
go: go1.25.5
goos: darwin
goarch: arm64
pkg: github.com/asmsh/uniquerand/v2
cpu: Apple M2
Benchmark_N/Get
Benchmark_N/Get/default-8 	                       91185	        58.67 ns/op	       0 B/op	       0 allocs/op
Benchmark_N/Get/min=0,step=1,max=32-8         	   94603	        60.21 ns/op	       0 B/op	       0 allocs/op
Benchmark_N/Get/min=0,step=1,max=64-8         	   98640	        61.02 ns/op	       0 B/op	       0 allocs/op
Benchmark_N/Get/min=0,step=1,max=256-8        	   86018	        70.70 ns/op	       0 B/op	       0 allocs/op
Benchmark_N/Get/min=0,step=1,max=1024-8       	   83439	        71.11 ns/op	       0 B/op	       0 allocs/op
Benchmark_N/Get/min=0,step=1,max=4096-8       	   75585	        87.93 ns/op	       0 B/op	       0 allocs/op

Benchmark_N/Put
Benchmark_N/Put/default-8                     	   80965	        68.84 ns/op	       0 B/op	       0 allocs/op
Benchmark_N/Put/min=0,step=1,max=32-8         	   83486	        68.97 ns/op	       0 B/op	       0 allocs/op
Benchmark_N/Put/min=0,step=1,max=64-8         	   87140	        69.03 ns/op	       0 B/op	       0 allocs/op
Benchmark_N/Put/min=0,step=1,max=256-8        	   70062	        82.47 ns/op	       0 B/op	       0 allocs/op
Benchmark_N/Put/min=0,step=1,max=1024-8       	   67519	        87.59 ns/op	       0 B/op	       0 allocs/op
Benchmark_N/Put/min=0,step=1,max=4096-8       	   69024	        84.04 ns/op	       0 B/op	       0 allocs/op

Benchmark_N/Get_&_Put
Benchmark_N/Get_&_Put/default-8               	  405747	        13.08 ns/op	       0 B/op	       0 allocs/op
Benchmark_N/Get_&_Put/min=0,step=1,max=32-8   	  475560	        12.25 ns/op	       0 B/op	       0 allocs/op
Benchmark_N/Get_&_Put/min=0,step=1,max=64-8   	  447067	        12.48 ns/op	       0 B/op	       0 allocs/op
Benchmark_N/Get_&_Put/min=0,step=1,max=256-8  	  367635	        15.76 ns/op	       0 B/op	       0 allocs/op
Benchmark_N/Get_&_Put/min=0,step=1,max=1024-8 	  413943	        14.57 ns/op	       0 B/op	       0 allocs/op
Benchmark_N/Get_&_Put/min=0,step=1,max=4096-8 	  428570	        13.61 ns/op	       0 B/op	       0 allocs/op

Benchmark_N/Clear_&_Get
Benchmark_N/Clear_&_Get/default-8             	  522496	        11.86 ns/op	       0 B/op	       0 allocs/op
Benchmark_N/Clear_&_Get/min=0,step=1,max=32-8 	  458305	        11.44 ns/op	       0 B/op	       0 allocs/op
Benchmark_N/Clear_&_Get/min=0,step=1,max=64-8 	  481123	        11.21 ns/op	       0 B/op	       0 allocs/op
Benchmark_N/Clear_&_Get/min=0,step=1,max=256-8    211863	        25.42 ns/op	      24 B/op	       1 allocs/op
Benchmark_N/Clear_&_Get/min=0,step=1,max=1024-8   171081	        32.01 ns/op	     128 B/op	       1 allocs/op
Benchmark_N/Clear_&_Get/min=0,step=1,max=4096-8    80049	        66.54 ns/op	     512 B/op	       1 allocs/op

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config[Int intType] struct {
	// Src is the source of the random numbers.
	// It takes a range, r, and returns a non-negative pseudo-random
	// number in the half-open interval [0,r).
	// If not passed, math/rand/v2.IntN is used.
	//
	// The range passed to this function, r, will be calculated as:
	//
	//  r := (Max - Min) / Step; if (Max - Min) % Step != 0 { r++ }
	Src func(r int) int

	// Min is the inclusive lower limit of the range.
	// All generated numbers will be greater than or equal to Min.
	Min Int

	// Max is the exclusive upper limit of the range.
	// If not set or set to 0, it defaults to 10.
	Max Int

	// Step is the difference between every two consecutive numbers in the range.
	// If not set or set to 0, it defaults to 1.
	Step Int
}

Config describes the generation criteria for the unique random numbers generated by N.

type Int

type Int = N[int]

Int is a typed N for returning [int] values within the default Config.

type N

type N[Int intType] struct {
	// contains filtered or unexported fields
}

N is a generator of unique random numbers with a specific criteria. It tracks used numbers to ensure uniqueness until the range is exhausted. The zero value is usable, defaulting to a range of [0, 10) with step of 1.

func NewN

func NewN[Int intType](config Config[Int]) *N[Int]

NewN creates a new N from the provided Config.

func (*N[Int]) All

func (rn *N[Int]) All() iter.Seq2[int, Int]

All returns an iterator over count-value pairs from rn, where the value is a unique random number, and count is the current N.Len, starting from 1. At any time, count <= N.Cap. Subsequent calls resumes any previous iterations.

func (*N[Int]) Cap

func (rn *N[Int]) Cap() int

Cap returns the number of unique random numbers that could be generated according to the set Config.

func (*N[Int]) Clear

func (rn *N[Int]) Clear()

Clear clears the state of this generator and resets its memory, making it able to regenerate values in the current Config. It doesn't change the generation Config. For changing the generation config use N.Config.

func (*N[Int]) Config

func (rn *N[Int]) Config(c Config[Int])

Config readies the random generator to be used, according to the Config provided. Each call discards any previous calls to either Config or Clear.

func (*N[Int]) Get

func (rn *N[Int]) Get() (v Int, ok bool)

Get generates a unique random number from the current Config and returns it and true. It returns 0 and false if the current Config is exhausted. The current Config can be set using N.Config. If no Config is set, it returns unique random numbers in the half-open interval [0,10), in steps of 1.

func (*N[Int]) Len

func (rn *N[Int]) Len() int

Len returns the number of unique random numbers already generated so far. Unique random numbers are generated using N.Get, and returned using N.Put. At any time, N.Len() <= N.Cap().

Example:

rn := N[int]{}
rn.Len() // returns 0
rn.Get()   // generates a unique random number
n := rn.Len()
rn.Put(n)  // returns the unique random number
rn.Len() // returns 0

func (*N[Int]) Max

func (rn *N[Int]) Max() Int

Max returns the exclusive upper limit of the unique random numbers. If the max has been set (via NewN or N.Config), Max returns it. If not been set, or set to 0, Max returns the default value (10).

Example:

rn := N[int]{}
rn.Max() // returns 10 (default max)
rn.Config(Config[int]{Max: 100})
rn.Max() // returns 100

func (*N[Int]) Min

func (rn *N[Int]) Min() Int

Min returns the inclusive lower limit of the unique random numbers. If the min has been set (via NewN or N.Config), Min returns it. If not set, it returns the zero value of the type.

func (*N[Int]) Put

func (rn *N[Int]) Put(v Int) (ok bool)

Put marks the previously generated unique random number, v, as not used, allowing it to be generated again later via N.Get. It returns true if v was generated before, or false otherwise.

func (*N[Int]) Step

func (rn *N[Int]) Step() Int

Step returns the difference between every two consecutive numbers in the range. If the step has been set (via NewN or N.Config), Step returns it. If not set, or set to 0, it returns the default value (1).

func (*N[Int]) Used

func (rn *N[Int]) Used(v Int) (ok bool)

Used returns true if v is consumed from the current Config, or false otherwise.

func (*N[Int]) Values

func (rn *N[Int]) Values() iter.Seq[Int]

Values returns an iterator over values from rn, where the value is a unique random number. Subsequent calls resumes any previous iterations.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL