bingo

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Mar 13, 2024 License: MIT Imports: 3 Imported by: 0

README

bingo

Go Report Card Go Reference Tests Coverage Mentioned in Awesome Go

Fast, zero-allocation, lexicographic-order-preserving packing/unpacking of native Go types to bytes.

Features

  • Encode bool, string, int8, int16, int32, int64, uint8, uint16, uint32, uint64, float32, float64, and time.Time
  • Packed values maintain original sort order
  • Pack values in descending order
  • Pack to an existing byte slice with no additional allocations
  • Create and pack values to a new byte slice (one allocation)
  • Unpack all values or just specific indexes

Usage

Import bingo:

import "github.com/iancmcc/bingo"
Packing
// Create and return a byte slice with encoded values
key := bingo.MustPack(uint8(12), "cool string bro")

// Now unpack
var (
    first uint8
    second string
)
bingo.Unpack(key, &first, &second)


// Pack so results will sort the second value descending
key = bingo.WithDesc(false, true, false).MustPack(1, time.Now(), true)

// Just unpack the middle value
var t time.Time
bingo.UnpackIndex(key, 1, &t)


// Pack to an existing byte slice
existingSlice := make([]byte, 100)
key := bingo.MustPackTo(existingSlice, uint16(7), "abc123")

Benchmarks

$ go test -bench BenchmarkCodecs
goos: linux
goarch: amd64
pkg: github.com/iancmcc/bingo
cpu: Intel(R) Core(TM) i7-7820HQ CPU @ 2.90GHz
BenchmarkCodecs/int8/encode/natural-8         	100000000	        10.35 ns/op	       0 B/op	       0 allocs/op
BenchmarkCodecs/int8/encode/inverse-8         	89794872	        12.60 ns/op	       0 B/op	       0 allocs/op
BenchmarkCodecs/int8/decode/natural-8         	65864187	        17.11 ns/op	       0 B/op	       0 allocs/op
BenchmarkCodecs/int8/decode/inverse-8         	63386660	        17.27 ns/op	       0 B/op	       0 allocs/op
BenchmarkCodecs/int16/encode/natural-8        	100000000	        10.04 ns/op	       0 B/op	       0 allocs/op
BenchmarkCodecs/int16/encode/inverse-8        	85618111	        13.08 ns/op	       0 B/op	       0 allocs/op
BenchmarkCodecs/int16/decode/natural-8        	64825372	        16.55 ns/op	       0 B/op	       0 allocs/op
BenchmarkCodecs/int16/decode/inverse-8        	58359490	        19.44 ns/op	       0 B/op	       0 allocs/op
BenchmarkCodecs/int32/encode/natural-8        	120393369	         9.942 ns/op	       0 B/op	       0 allocs/op
BenchmarkCodecs/int32/encode/inverse-8        	80418766	        13.67 ns/op	       0 B/op	       0 allocs/op
BenchmarkCodecs/int32/decode/natural-8        	53423986	        21.03 ns/op	       0 B/op	       0 allocs/op
BenchmarkCodecs/int32/decode/inverse-8        	47975257	        24.68 ns/op	       0 B/op	       0 allocs/op
BenchmarkCodecs/int64/encode/natural-8        	100000000	        10.95 ns/op	       0 B/op	       0 allocs/op
BenchmarkCodecs/int64/encode/inverse-8        	67093402	        17.79 ns/op	       0 B/op	       0 allocs/op
BenchmarkCodecs/int64/decode/natural-8        	47149765	        23.97 ns/op	       0 B/op	       0 allocs/op
BenchmarkCodecs/int64/decode/inverse-8        	39063907	        27.36 ns/op	       0 B/op	       0 allocs/op
BenchmarkCodecs/float32/encode/natural-8      	100000000	        10.42 ns/op	       0 B/op	       0 allocs/op
BenchmarkCodecs/float32/encode/inverse-8      	79910834	        14.11 ns/op	       0 B/op	       0 allocs/op
BenchmarkCodecs/float32/decode/natural-8      	63494347	        16.88 ns/op	       0 B/op	       0 allocs/op
BenchmarkCodecs/float32/decode/inverse-8      	46677241	        25.55 ns/op	       0 B/op	       0 allocs/op
BenchmarkCodecs/float64/encode/natural-8      	100000000	        11.05 ns/op	       0 B/op	       0 allocs/op
BenchmarkCodecs/float64/encode/inverse-8      	62377978	        17.48 ns/op	       0 B/op	       0 allocs/op
BenchmarkCodecs/float64/decode/natural-8      	62370994	        17.26 ns/op	       0 B/op	       0 allocs/op
BenchmarkCodecs/float64/decode/inverse-8      	54139144	        20.68 ns/op	       0 B/op	       0 allocs/op
BenchmarkCodecs/string/encode/natural-8       	47404435	        23.80 ns/op	       0 B/op	       0 allocs/op
BenchmarkCodecs/string/encode/inverse-8       	29144544	        39.74 ns/op	       0 B/op	       0 allocs/op
BenchmarkCodecs/string/decode/natural-8       	39683684	        31.39 ns/op	       0 B/op	       0 allocs/op
BenchmarkCodecs/string/decode/inverse-8       	23373333	        48.06 ns/op	       0 B/op	       0 allocs/op
BenchmarkCodecs/time/encode/natural-8         	47027752	        24.72 ns/op	       0 B/op	       0 allocs/op
BenchmarkCodecs/time/encode/inverse-8         	38363001	        29.22 ns/op	       0 B/op	       0 allocs/op
BenchmarkCodecs/time/decode/natural-8         	42566337	        26.76 ns/op	       0 B/op	       0 allocs/op
BenchmarkCodecs/time/decode/inverse-8         	30851250	        36.88 ns/op	       0 B/op	       0 allocs/op
PASS
ok  	github.com/iancmcc/bingo	37.644s

Documentation

Overview

Package bingo packs values into composite keys, using a byte encoding that preserves the sort order of the original values.

Many of the encoding formats are the same as those used in HBase's OrderedBytes class, which were in turn modeled after encoding formats defined by SQLite4 and Orderly.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func MustPack

func MustPack(vals ...interface{}) []byte

MustPack encodes the values passed, returning the resulting byte slice. Panics on error.

func MustPackTo

func MustPackTo(b []byte, vals ...interface{}) int

MustPackTo encodes the values passed into the provided byte slice, returning the number of bytes written. Panics on error.

func Pack

func Pack(vals ...interface{}) ([]byte, error)

Pack encodes the values passed, returning the resulting byte slice. This requires 1 heap alloc for the return value.

Example
package main

import (
	"bytes"
	"fmt"
	"sort"

	"github.com/iancmcc/bingo"
)

func main() {
	// Pack some values into keys
	a, _ := bingo.Pack(1, "b", float32(4.2))
	b, _ := bingo.Pack(1, "b", float32(3.1))
	c, _ := bingo.Pack(1, "a", float32(7.5))

	// Sort the resulting byte slices
	packed := [][]byte{a, b, c}
	sort.SliceStable(packed, func(p, q int) bool {
		return bytes.Compare(packed[p], packed[q]) < 0
	})

	// Unpack again and witness the glorious order
	var (
		first  int
		second string
		third  float32
	)
	for _, bs := range packed {
		bingo.Unpack(bs, &first, &second, &third)
		fmt.Println(first, second, third)
	}
}
Output:

1 a 7.5
1 b 3.1
1 b 4.2

func PackTo

func PackTo(b []byte, vals ...interface{}) (n int, err error)

PackTo encodes the values passed into the provided byte slice, returning the number of bytes written.

Example
package main

import (
	"time"

	"github.com/iancmcc/bingo"
)

func main() {
	// Pack requires an allocation for the resulting byte array, but you can
	// also pack to a byte array you already have

	values := []interface{}{1, "a", time.Now()}

	// Get the size you'll need
	size, _ := bingo.PackedSize(values)
	dest := make([]byte, size)

	bingo.PackTo(dest, values...)
}
Output:

func PackedSize

func PackedSize(vals []interface{}) (int, error)

PackedSize returns the number of bytes required to pack the values passed

func Unpack

func Unpack(b []byte, dests ...interface{}) error

Unpack unpacks b into the targets provided.

func UnpackIndex

func UnpackIndex(b []byte, idx int, dest interface{}) error

UnpackIndex unpacks the idx'th value from b into the target provided.

func WritePackedTo

func WritePackedTo(w io.Writer, vals ...interface{}) (n int, err error)

WritePackedTo encodes the values passed and writes the result to the io.Writer specified. Note: this requires 1 heap alloc for the intermediate byte array.

Example
package main

import (
	"bytes"
	"fmt"

	"github.com/iancmcc/bingo"
)

func main() {
	var buf bytes.Buffer

	bingo.WritePackedTo(&buf, 1, "a")

	var (
		first  int
		second string
	)
	bingo.Unpack(buf.Bytes(), &first, &second)

	fmt.Println(first, second)
}
Output:

1 a

Types

type Schema

type Schema uint64

Schema captures whether fields of a key should be encoded in inverse or natural order.

func WithDesc

func WithDesc(cols ...bool) Schema

WithDesc returns a Schema that will produce packed keys with the indicated values encoded to sort in descending order.

Example
package main

import (
	"bytes"
	"fmt"
	"sort"

	"github.com/iancmcc/bingo"
)

func main() {
	// Create a schema that packs the second value in descending order
	schema := bingo.WithDesc(false, true, false)

	// Pack some values into keys
	a, _ := schema.Pack(1, "b", float32(4.2))
	b, _ := schema.Pack(1, "b", float32(3.1))
	c, _ := schema.Pack(1, "a", float32(7.5))

	// Sort the resulting byte slices
	packed := [][]byte{a, b, c}
	sort.SliceStable(packed, func(p, q int) bool {
		return bytes.Compare(packed[p], packed[q]) < 0
	})

	// Unpack to see the order
	var (
		first  int
		second string
		third  float32
	)
	for _, bs := range packed {
		bingo.Unpack(bs, &first, &second, &third)
		fmt.Println(first, second, third)
	}
}
Output:

1 b 3.1
1 b 4.2
1 a 7.5

func (Schema) MustPack

func (s Schema) MustPack(vals ...interface{}) []byte

MustPack encodes the values passed, returning the resulting byte slice and panicking on error.

func (Schema) MustPackTo

func (s Schema) MustPackTo(b []byte, vals ...interface{}) int

MustPackTo encodes the values passed into the provided byte slice, returning the number of bytes written. Panics on error.

func (Schema) Pack

func (s Schema) Pack(vals ...interface{}) ([]byte, error)

Pack encodes the values passed, returning the resulting byte slice.

func (Schema) PackTo

func (s Schema) PackTo(b []byte, vals ...interface{}) (n int, err error)

PackTo encodes the values passed into the provided byte slice, returning the number of bytes written.

func (Schema) WritePackedTo

func (s Schema) WritePackedTo(w io.Writer, vals ...interface{}) (n int, err error)

WritePackedTo encodes the values passed and writes the result to the io.Writer specified. Note: this requires 1 heap alloc for the intermediate byte array.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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