ident: system identifier generator

This is pretty fast and guarantees uniqueness when initialised correctly.

Signed-off-by: Yonah <contrib@gensokyo.uk>
This commit is contained in:
2026-03-22 22:22:04 +09:00
parent 22b8cc3884
commit 338cb1e000
5 changed files with 81 additions and 14 deletions

View File

@@ -6,7 +6,10 @@ import (
"encoding" "encoding"
"errors" "errors"
"fmt" "fmt"
"math/rand/v2"
"strconv" "strconv"
"sync"
"time"
"unsafe" "unsafe"
) )
@@ -97,3 +100,47 @@ func (full *F[V, T]) UnmarshalText(data []byte) (err error) {
} }
return full.Remote.UnmarshalText(data[sz+1:]) return full.Remote.UnmarshalText(data[sz+1:])
} }
// PartG is machine-specific state of [Generator].
type PartG struct {
// Deployment site, typically denoting a datacenter servicing a region.
Site uint32
// Servicing host behind load balancer, unique within its Site.
Host uint32
}
// A Generator emits unique instances of [S].
type Generator struct {
PartG
mu sync.Mutex
r rand.Source
}
// S populates the value pointed to by p with a new unique value.
func (g *Generator) S(p *S) {
g.mu.Lock()
*p = S{PartG: g.PartG, Time: uint64(time.Now().UnixNano()), ID: g.r.Uint64()}
g.mu.Unlock()
}
// NewS creates a unique instance of [S] and returns its address.
func (g *Generator) NewS() *S {
var sid S
g.S(&sid)
return &sid
}
// M populates the value pointed to by p with a new unique value.
func (g *Generator) M(p *PartM, serial uint64) {
g.mu.Lock()
*p = PartM{Serial: serial, Time: uint64(time.Now().UnixNano()), ID: g.r.Uint64()}
g.mu.Unlock()
}
// New initialises a new instance of [Generator] and returns its address.
func New(site, host uint32) *Generator {
return &Generator{PartG{site, host}, sync.Mutex{}, rand.NewPCG(
uint64(site)<<32|uint64(host),
uint64(time.Now().UnixNano()),
)}
}

View File

@@ -89,8 +89,10 @@ func TestFS(t *testing.T) {
{"valid", ident.F[ident.S, *ident.S]{ {"valid", ident.F[ident.S, *ident.S]{
I: &ident.S{ I: &ident.S{
Site: ident.TrivialSite, PartG: ident.PartG{
Host: ident.TrivialHost, Site: ident.TrivialSite,
Host: ident.TrivialHost,
},
Time: uint64(time.Date( Time: uint64(time.Date(
0xfd, 7, 15, 0xfd, 7, 15,
@@ -130,8 +132,10 @@ func TestFM(t *testing.T) {
}, },
System: ident.S{ System: ident.S{
Site: ident.TrivialSite, PartG: ident.PartG{
Host: ident.TrivialHost, Site: ident.TrivialSite,
Host: ident.TrivialHost,
},
Time: uint64(time.Date( Time: uint64(time.Date(
0xfd, 7, 15, 0xfd, 7, 15,
@@ -207,3 +211,19 @@ func TestErrors(t *testing.T) {
}) })
} }
} }
func BenchmarkGeneratorS(b *testing.B) {
var s ident.S
g := ident.New(ident.TrivialSite, ident.TrivialHost)
for b.Loop() {
g.S(&s)
}
}
func BenchmarkGeneratorM(b *testing.B) {
var pm ident.PartM
g := ident.New(ident.TrivialSite, ident.TrivialHost)
for b.Loop() {
g.M(&pm, 0xbadf00d)
}
}

View File

@@ -98,8 +98,10 @@ func TestM(t *testing.T) {
}, },
System: ident.S{ System: ident.S{
Site: ident.TrivialSite, PartG: ident.PartG{
Host: ident.TrivialHost, Site: ident.TrivialSite,
Host: ident.TrivialHost,
},
Time: uint64(time.Date( Time: uint64(time.Date(
0xfd, 7, 15, 0xfd, 7, 15,

View File

@@ -17,17 +17,13 @@ const (
// S represents a unique system identifier. // S represents a unique system identifier.
type S struct { type S struct {
// Deployment site, typically denoting a datacenter servicing a region. PartG
Site uint32
// Servicing host behind load balancer, unique within its Site.
Host uint32
// An instant in time, some time after the corresponding system metadata // An instant in time, some time after the corresponding system metadata
// first appeared to the backend, represented in nanoseconds since // first appeared to the backend, represented in nanoseconds since
// 1970-01-01. // 1970-01-01.
Time uint64 Time uint64
// Randomly generated value. The implementation must guarantee that the same // Randomly generated value. The implementation must guarantee that the same
// value cannot be emitted for a Time value on a servicing Host. // value cannot be emitted for a Time value on a servicing host.
ID uint64 ID uint64
} }

View File

@@ -34,8 +34,10 @@ func TestS(t *testing.T) {
), ident.ErrNewline}, ), ident.ErrNewline},
{"valid", ident.S{ {"valid", ident.S{
Site: ident.TrivialSite, PartG: ident.PartG{
Host: ident.TrivialHost, Site: ident.TrivialSite,
Host: ident.TrivialHost,
},
Time: uint64(time.Date( Time: uint64(time.Date(
0xfd, 7, 15, 0xfd, 7, 15,