Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(examples): add p/demo/seqid #1378

Merged
merged 5 commits into from
Nov 16, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions examples/gno.land/p/demo/squid/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# squid
thehowl marked this conversation as resolved.
Show resolved Hide resolved

```
package squid // import "gno.land/p/demo/squid"

Package squid provides a simple way to have sequential IDs which will be ordered
correctly when inserted in an AVL tree.

Sample usage:

var id squid.ID
var users avl.Tree

func NewUser() {
users.Set(id.Next().Binary(), &User{ ... })
}

TYPES

type ID uint64
An ID is a simple sequential ID generator.

func FromBinary(b string) (ID, bool)
FromBinary creates a new ID from the given string.

func (i ID) Binary() string
Binary returns a big-endian binary representation of the ID, suitable to be
used as an AVL key.

func (i *ID) Next() ID
Next advances the ID i. It will panic if increasing ID would overflow.

func (i *ID) TryNext() (ID, bool)
TryNext increases i by 1 and returns its value. It returns true if
successful, or false if the increment would result in an overflow.
```
1 change: 1 addition & 0 deletions examples/gno.land/p/demo/squid/gno.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module gno.land/p/demo/squid
57 changes: 57 additions & 0 deletions examples/gno.land/p/demo/squid/squid.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Package squid provides a simple way to have sequential IDs which will be
// ordered correctly when inserted in an AVL tree.
//
// Sample usage:
//
// var id squid.ID
// var users avl.Tree
//
// func NewUser() {
// users.Set(id.Next().Binary(), &User{ ... })
// }
package squid

import "encoding/binary"

// An ID is a simple sequential ID generator.
type ID uint64

// Next advances the ID i.
// It will panic if increasing ID would overflow.
func (i *ID) Next() ID {
next, ok := i.TryNext()
if !ok {
panic("squid: next ID overflows uint64")
}
return next
}

const maxID ID = 1<<64 - 1

// TryNext increases i by 1 and returns its value.
// It returns true if successful, or false if the increment would result in
// an overflow.
func (i *ID) TryNext() (ID, bool) {
if *i == maxID {
// Addition will overflow.
return 0, false
}
*i++
return *i, true
}

// Binary returns a big-endian binary representation of the ID,
// suitable to be used as an AVL key.
func (i ID) Binary() string {
buf := make([]byte, 8)
binary.BigEndian.PutUint64(buf, uint64(i))
return string(buf)
}

// FromBinary creates a new ID from the given string.
func FromBinary(b string) (ID, bool) {
if len(b) != 8 {
return 0, false
}
return ID(binary.BigEndian.Uint64([]byte(b))), true
}
43 changes: 43 additions & 0 deletions examples/gno.land/p/demo/squid/squid_test.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package squid

import (
"fmt"
"strings"
"testing"
)

func TestID(t *testing.T) {
var i ID

for j := 0; j < 100; j++ {
i.Next()
}
if i != 100 {
t.Fatalf("invalid: wanted %d got %d", 100, i)
}
}

func TestID_Overflow(t *testing.T) {
i := ID(maxID)

defer func() {
err := recover()
if !strings.Contains(fmt.Sprint(err), "next ID overflows") {
t.Errorf("did not overflow")
}
}()

i.Next()
}

func TestID_Binary(t *testing.T) {
var i ID
prev := i.Binary()

for j := 0; j < 1000; j++ {
cur := i.Next().Binary()
if cur <= prev {
t.Fatalf("cur %x <= prev %x", cur, prev)
}
}
}
Loading