Skip to content

Commit

Permalink
Merge pull request #7 from mustafaturan/introduce_max_node_method
Browse files Browse the repository at this point in the history
Introduce MaxNode method on sequencer
  • Loading branch information
mustafaturan authored Dec 11, 2021
2 parents 6145bb2 + 6c134e3 commit 3496bed
Show file tree
Hide file tree
Showing 13 changed files with 59 additions and 33 deletions.
4 changes: 1 addition & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
language: go

go:
- 1.16.x
- master
- tip
- 1.17.x

before_install:
- go get golang.org/x/tools/cmd/cover
Expand Down
24 changes: 12 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@
[![Build Status](https://travis-ci.org/mustafaturan/monoton.svg?branch=master)](https://travis-ci.org/mustafaturan/monoton)
[![Coverage Status](https://coveralls.io/repos/github/mustafaturan/monoton/badge.svg?branch=master)](https://coveralls.io/github/mustafaturan/monoton?branch=main)
[![Go Report Card](https://goreportcard.com/badge/github.com/mustafaturan/monoton)](https://goreportcard.com/report/github.com/mustafaturan/monoton)
[![GoDoc](https://godoc.org/github.com/mustafaturan/monoton?status.svg)](https://godoc.org/github.com/mustafaturan/monoton/v2)
[![GoDoc](https://godoc.org/github.com/mustafaturan/monoton?status.svg)](https://godoc.org/github.com/mustafaturan/monoton/v3)

Highly scalable, single/multi node, predictable and incremental unique id
generator with zero allocation magic.

## Installation

Via go packages:
```go get github.com/mustafaturan/monoton/v2```
```go get github.com/mustafaturan/monoton/v3```

## API

The method names and arities/args are stable now. No change should be expected
on the package for the version `2.x.x` except any bug fixes.
on the package for the version `3.x.x` except any bug fixes.

## Usage

Expand All @@ -30,8 +30,8 @@ package uniqid
// Import packages
import (
"fmt"
"github.com/mustafaturan/monoton/v2"
"github.com/mustafaturan/monoton/v2/sequencer"
"github.com/mustafaturan/monoton/v3"
"github.com/mustafaturan/monoton/v3/sequencer"
)

var m monoton.Monoton
Expand Down Expand Up @@ -93,8 +93,8 @@ package main
// Import packages
import (
"fmt"
"github.com/mustafaturan/monoton/v2"
"github.com/mustafaturan/monoton/v2/sequencer"
"github.com/mustafaturan/monoton/v3"
"github.com/mustafaturan/monoton/v3/sequencer"
)

func NewIDGenerator() monoton.Monoton {
Expand Down Expand Up @@ -187,19 +187,19 @@ implementing the `monoton/sequencer.Sequencer` interface.

Command:
```
go test -benchtime 10000000x -benchmem -run=^$ -bench=. github.com/mustafaturan/monoton/v2
go test -benchtime 10000000x -benchmem -run=^$ -bench=. github.com/mustafaturan/monoton/v3
```

Results:
```
goos: darwin
goarch: amd64
pkg: github.com/mustafaturan/monoton/v2
pkg: github.com/mustafaturan/monoton/v3
cpu: Intel(R) Core(TM) i5-6267U CPU @ 2.90GHz
BenchmarkNext-4 10000000 108.7 ns/op 0 B/op 0 allocs/op
BenchmarkNextBytes-4 10000000 99.88 ns/op 0 B/op 0 allocs/op
BenchmarkNext-4 10000000 102.3 ns/op 0 B/op 0 allocs/op
BenchmarkNextBytes-4 10000000 97.51 ns/op 0 B/op 0 allocs/op
PASS
ok github.com/mustafaturan/monoton/v2 2.194s
ok github.com/mustafaturan/monoton/v3 2.203s
```

## Contributing
Expand Down
4 changes: 2 additions & 2 deletions benchmark_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package monoton_test
import (
"testing"

"github.com/mustafaturan/monoton/v2"
"github.com/mustafaturan/monoton/v2/sequencer"
"github.com/mustafaturan/monoton/v3"
"github.com/mustafaturan/monoton/v3/sequencer"
)

func BenchmarkNext(b *testing.B) {
Expand Down
4 changes: 2 additions & 2 deletions example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (
"fmt"
"time"

"github.com/mustafaturan/monoton/v2"
"github.com/mustafaturan/monoton/v2/sequencer"
"github.com/mustafaturan/monoton/v3"
"github.com/mustafaturan/monoton/v3/sequencer"
)

func ExampleNew() {
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module github.com/mustafaturan/monoton/v2
module github.com/mustafaturan/monoton/v3

go 1.16
16 changes: 8 additions & 8 deletions monoton.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ Example using Singleton
// Import packages
import (
"fmt"
"github.com/mustafaturan/monoton/v2"
"github.com/mustafaturan/monoton/v2/sequencer"
"github.com/mustafaturan/monoton/v3"
"github.com/mustafaturan/monoton/v3/sequencer"
)
const year2020asMillisecondPST = 1577865600000
Expand Down Expand Up @@ -117,10 +117,9 @@ package monoton

import (
"fmt"
"math"

"github.com/mustafaturan/monoton/v2/encoder"
"github.com/mustafaturan/monoton/v2/sequencer"
"github.com/mustafaturan/monoton/v3/encoder"
"github.com/mustafaturan/monoton/v3/sequencer"
)

const (
Expand Down Expand Up @@ -223,11 +222,12 @@ func (m Monoton) NextBytes() [16]byte {
}

func (m *Monoton) configureByteSizes() error {
maxNodeSeqByteSize := encoder.Base62ByteSize(m.sequencer.MaxNode())
maxTimeSeqByteSize := encoder.Base62ByteSize(m.sequencer.MaxTime())
maxSeqByteSize := encoder.Base62ByteSize(m.sequencer.Max())

// At least one byte slot is necessary for the node
if maxTimeSeqByteSize+maxSeqByteSize >= totalByteSize {
// The sum is always 16 bytes
if maxTimeSeqByteSize+maxSeqByteSize+maxNodeSeqByteSize != totalByteSize {
return &MaxByteSizeError{
ByteSizeSequence: maxSeqByteSize,
ByteSizeSequenceTime: maxTimeSeqByteSize,
Expand All @@ -251,7 +251,7 @@ func (m *Monoton) configureNode(node uint64) error {
}

func (m Monoton) validateNode(node uint64) error {
maxNode := uint64(math.Pow(62, float64(m.nodeByteSize()))) - 1
maxNode := m.sequencer.MaxNode()
if node > maxNode {
return &MaxNodeCapacityExceededError{Node: node, MaxNode: maxNode}
}
Expand Down
10 changes: 9 additions & 1 deletion monoton_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"strings"
"testing"

"github.com/mustafaturan/monoton/v2/sequencer"
"github.com/mustafaturan/monoton/v3/sequencer"
)

func TestNew(t *testing.T) {
Expand Down Expand Up @@ -148,6 +148,10 @@ type invalidSequencer struct {
counter uint64
}

func (v *validSequencer) MaxNode() uint64 {
return uint64(math.Pow(62, 2)) - 1
}

func (v *validSequencer) MaxTime() uint64 {
return uint64(math.Pow(62, 8)) - 1
}
Expand All @@ -161,6 +165,10 @@ func (v *validSequencer) Next() (uint64, uint64) {
return 1, v.counter
}

func (i *invalidSequencer) MaxNode() uint64 {
return uint64(math.Pow(62, 3)) - 1
}

func (i *invalidSequencer) MaxTime() uint64 {
return uint64(math.Pow(62, 8)) - 1
}
Expand Down
3 changes: 2 additions & 1 deletion sequencer/millisecond.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ package sequencer
import (
"time"

"github.com/mustafaturan/monoton/v2/mtimer"
"github.com/mustafaturan/monoton/v3/mtimer"
)

// NewMillisecond returns the preconfigured millisecond sequencer
Expand All @@ -18,5 +18,6 @@ func NewMillisecond() *Sequence {
now: func() uint64 { return timer.Now() / millisecond },
max: 62*62*62*62 - 1,
maxTime: 62*62*62*62*62*62*62*62 - 1,
maxNode: 62*62*62*62 - 1,
}
}
3 changes: 2 additions & 1 deletion sequencer/nanosecond.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
package sequencer

import (
"github.com/mustafaturan/monoton/v2/mtimer"
"github.com/mustafaturan/monoton/v3/mtimer"
)

// NewNanosecond returns the preconfigured nanosecond sequencer
Expand All @@ -15,5 +15,6 @@ func NewNanosecond() *Sequence {
now: timer.Now,
max: 62*62 - 1,
maxTime: uint64(1<<64 - 1),
maxNode: 62*62*62 - 1,
}
}
3 changes: 2 additions & 1 deletion sequencer/second.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ package sequencer
import (
"time"

"github.com/mustafaturan/monoton/v2/mtimer"
"github.com/mustafaturan/monoton/v3/mtimer"
)

// NewSecond returns the preconfigured second sequencer
Expand All @@ -18,5 +18,6 @@ func NewSecond() *Sequence {
now: func() uint64 { return timer.Now() / second },
max: 62*62*62*62*62*62 - 1,
maxTime: 62*62*62*62*62*62 - 1,
maxNode: 62*62*62*62 - 1,
}
}
6 changes: 6 additions & 0 deletions sequencer/sequence.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type Sequence struct {
time uint64
max uint64
maxTime uint64
maxNode uint64
now func() uint64
}

Expand All @@ -27,6 +28,11 @@ func (s *Sequence) MaxTime() uint64 {
return s.maxTime
}

// MaxNode returns the maximum possible node value
func (s *Sequence) MaxNode() uint64 {
return s.maxNode
}

// Next returns the next sequence
func (s *Sequence) Next() (uint64, uint64) {
now := s.now()
Expand Down
11 changes: 10 additions & 1 deletion sequencer/sequence_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"testing"
"time"

"github.com/mustafaturan/monoton/v2/mtimer"
"github.com/mustafaturan/monoton/v3/mtimer"
)

func TestMax_Sequence(t *testing.T) {
Expand All @@ -29,6 +29,15 @@ func TestMaxTime_Sequence(t *testing.T) {
}
}

func TestMaxNode_Sequence(t *testing.T) {
want := uint64(1<<64 - 1)
s := &Sequence{maxNode: want}

if got := s.MaxNode(); got != want {
t.Errorf("Max() want: %d, got: %d", want, got)
}
}

func TestNext_Sequence(t *testing.T) {
timer := mtimer.New()
tests := []struct {
Expand Down
2 changes: 2 additions & 0 deletions sequencer/sequencer.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ type Sequencer interface {
Max() uint64
// MaxTime returns the maximum possible time sequence value
MaxTime() uint64
// MaxNode returns the maximum possible node value
MaxNode() uint64
// Now returns the current monotonic time
Next() (uint64, uint64)
}

0 comments on commit 3496bed

Please sign in to comment.