-
Notifications
You must be signed in to change notification settings - Fork 386
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
137 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# squid | ||
|
||
``` | ||
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. | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
module gno.land/p/demo/squid |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 maxUint64 uint64 = 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 == maxUint64 { | ||
// 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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package squid | ||
|
||
import ( | ||
"strings" | ||
"testing" | ||
"fmt" | ||
) | ||
|
||
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(maxUint64) | ||
|
||
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) | ||
} | ||
} | ||
} |