sak

package
v1.0.6 Latest Latest
Warning

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

Go to latest
Published: Nov 2, 2022 License: Apache-2.0 Imports: 3 Imported by: 0

Documentation

Overview

package "sak" (Swiss Army knife) provides some basic util functions

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Abs

func Abs[T SignedNumber](a T) T

A generic version of math.Abs.

func MapCopy

func MapCopy[K comparable, T any](m map[K]T) map[K]T

A utility function that copies a map[K]T. Useful when you need to iterate over items in a map that is synchronized buy a Mutex. Used internally but exposed for your consumption.

func MapKeysToSlice

func MapKeysToSlice[K comparable, T any](m map[K]T) []K

A utility function that extracts all keys from a map[K]T. Useful when you need to iterate over keys in a map that is synchronized buy a Mutex. Used internally but exposed for your consumption.

func MapValuesToSlice

func MapValuesToSlice[K comparable, T any](m map[K]T) []T

A utility function that extracts all values from a map[K]T. Useful when you need to iterate over items in a map that is synchronized buy a Mutex. Used internally but exposed for your consumption.

func Max

func Max[T Number](a, b T) T

A generic version of math.Max.

Example
package main

import (
	"fmt"

	"github.com/aws/go-kafka-event-source/streams/sak"
)

func main() {
	a := uint16(1)
	b := uint16(2)
	max := sak.Max(a, b)
	fmt.Println(max)
}
Output:

2

func MaxN

func MaxN[T Number](vals ...T) (max T)

A generic version of math.Max with the added bonus of accepting more than 2 arguments.

Example
package main

import (
	"fmt"

	"github.com/aws/go-kafka-event-source/streams/sak"
)

func main() {
	vals := []int{1, 9, 4, 10, -1, 25}
	max := sak.MaxN(vals...)
	fmt.Println(max)
}
Output:

25

func Min

func Min[T Number](a, b T) T

A generic version of math.Min.

Example
package main

import (
	"fmt"

	"github.com/aws/go-kafka-event-source/streams/sak"
)

func main() {
	a := uint16(1)
	b := uint16(2)
	min := sak.Min(a, b)
	fmt.Println(min)
}
Output:

1

func MinN

func MinN[T Number](vals ...T) (min T)

A generic version of math.Min with the added bonus of accepting more than 2 arguments.

Example
package main

import (
	"fmt"

	"github.com/aws/go-kafka-event-source/streams/sak"
)

func main() {
	vals := []int{1, 9, 4, 10, -1, 25}
	min := sak.MinN(vals...)
	fmt.Println(min)
}
Output:

-1

func Must

func Must[T any](item T, err error) T

A convenience method for panicking on errors. Useful for simplifying code when calling methods that should never error, or when thre is no way to recover from the error.

Example
package main

import (
	"fmt"

	"github.com/aws/go-kafka-event-source/streams/sak"
)

type Encoder[T any] func(T) ([]byte, error)

func encodeString(s string) ([]byte, error) {
	return []byte(s), nil
}

func main() {
	var encode Encoder[string] = encodeString
	b := sak.Must(encode("Hello World!"))
	fmt.Println(len(b))
}
Output:

12

func Noescape

func Noescape(p unsafe.Pointer) unsafe.Pointer

Noescape hides a pointer from escape analysis. noescape is the identity function but escape analysis doesn't think the output depends on the input. USE CAREFULLY!

func Ptr

func Ptr[T any](v T) *T

Simple utilty for swapping struct T to a ptr T Wether or not this creates a heap escape is up to the compiler. This method simply return &v

func ToPtrSlice

func ToPtrSlice[T any](structs []T) []*T

A utility function that converts a slice of T to a slice of *T. Useful when you don't want consumer of your package to be able to mutate an argument passed to you, but you need to mutate it internally (accept a slice of structs, then swap them to pointers). This methos forces a heap escape via

ptr := new(T)

Used internally but exposed for your consumption.

func ToStructSlice

func ToStructSlice[T any](ptrs []*T) []T

The inverse of ToPtrSlice. Useful when you're doing some type gymnastics. Not used internally but, seems only correct to supply the inverse.

Types

type Element

type Element[T any] struct {

	// The value stored with this element.
	Value T
	// contains filtered or unexported fields
}

Element is an element of a linked list.

func (*Element[T]) Next

func (e *Element[T]) Next() *Element[T]

Next returns the next list element or nil.

func (*Element[T]) Prev

func (e *Element[T]) Prev() *Element[T]

Prev returns the previous list element or nil.

type Float

type Float interface {
	~float32 | ~float64
}

type List

type List[T any] struct {
	// contains filtered or unexported fields
}

List represents a doubly linked list. The zero value for List is an empty list ready to use.

func NewList

func NewList[T any]() *List[T]

NewList returns an initialized list.

func (*List[T]) Back

func (l *List[T]) Back() *Element[T]

Back returns the last element of list l or nil if the list is empty.

func (*List[T]) Front

func (l *List[T]) Front() *Element[T]

Front returns the first element of list l or nil if the list is empty.

func (*List[T]) Init

func (l *List[T]) Init() *List[T]

Init initializes or clears list l.

func (*List[T]) InsertAfter

func (l *List[T]) InsertAfter(v T, mark *Element[T]) *Element[T]

InsertAfter inserts a new element e with value v immediately after mark and returns e. If mark is not an element of l, the list is not modified. The mark must not be nil.

func (*List[T]) InsertBefore

func (l *List[T]) InsertBefore(v T, mark *Element[T]) *Element[T]

InsertBefore inserts a new element e with value v immediately before mark and returns e. If mark is not an element of l, the list is not modified. The mark must not be nil.

func (*List[T]) Len

func (l *List[T]) Len() int

Len returns the number of elements of list l. The complexity is O(1).

func (*List[T]) MoveAfter

func (l *List[T]) MoveAfter(e, mark *Element[T])

MoveAfter moves element e to its new position after mark. If e or mark is not an element of l, or e == mark, the list is not modified. The element and mark must not be nil.

func (*List[T]) MoveBefore

func (l *List[T]) MoveBefore(e, mark *Element[T])

MoveBefore moves element e to its new position before mark. If e or mark is not an element of l, or e == mark, the list is not modified. The element and mark must not be nil.

func (*List[T]) MoveToBack

func (l *List[T]) MoveToBack(e *Element[T])

MoveToBack moves element e to the back of list l. If e is not an element of l, the list is not modified. The element must not be nil.

func (*List[T]) MoveToFront

func (l *List[T]) MoveToFront(e *Element[T])

MoveToFront moves element e to the front of list l. If e is not an element of l, the list is not modified. The element must not be nil.

func (*List[T]) PushBack

func (l *List[T]) PushBack(v T) *Element[T]

PushBack inserts a new element e with value v at the back of list l and returns e.

func (*List[T]) PushBackList

func (l *List[T]) PushBackList(other *List[T])

PushBackList inserts a copy of another list at the back of list l. The lists l and other may be the same. They must not be nil.

func (*List[T]) PushFront

func (l *List[T]) PushFront(v T) *Element[T]

PushFront inserts a new element e with value v at the front of list l and returns e.

func (*List[T]) PushFrontList

func (l *List[T]) PushFrontList(other *List[T])

PushFrontList inserts a copy of another list at the front of list l. The lists l and other may be the same. They must not be nil.

func (*List[T]) Remove

func (l *List[T]) Remove(e *Element[T]) T

Remove removes e from l if e is an element of list l. It returns the element value e.Value. The element must not be nil.

type Number

type Number interface {
	Signed | Unsigned | Float
}

type Pool

type Pool[T any] struct {
	// contains filtered or unexported fields
}

Pool is a generic alternative to sync.Pool, but more akin to "Free List". It does not function in the same way however. It is simply a capped list of objects controlled by a mutex. In many situations, this will sak.Pool will outperform sync.Pool, however the memory management is very rudimentary and does not provide the same benefits. There is however, much less overhead than a standard sync.Pool.

Example
package main

import (
	"fmt"

	"github.com/aws/go-kafka-event-source/streams/sak"
)

func newIntArray() []int {
	return make([]int, 0)
}

func releaseIntArray(a []int) []int {
	return a[0:0]
}

func main() {
	intArrayPool := sak.NewPool(100, newIntArray, releaseIntArray)
	a := intArrayPool.Borrow()
	for i := 0; i < 10; i++ {
		a = append(a, i)
	}
	fmt.Println(len(a))
	intArrayPool.Release(a)

	b := intArrayPool.Borrow()
	fmt.Println(len(b))
}
Output:

10
0

func NewPool

func NewPool[T any](size int, factory func() T, resetter func(T) T) *Pool[T]

NewPool creates a new free list. size is the maximum size of the returned free list. `factory` is the function which allocates new objects when necessary. `resetter` is optional, but when provided, is invoked on `Release`, before returning the object to the pool.

func (*Pool[T]) Borrow

func (p *Pool[T]) Borrow() (n T)

Returns an item from the pool. If none are available, invokes `pool.factory` and return the result.

func (*Pool[T]) Release

func (p *Pool[T]) Release(n T) (out bool)

Returns an item to the pool if there is space available. If a `resetter` function is provided, it is invoked regardless of wether the item is returned to the pool or not.

type RunStatus

type RunStatus struct {
	// contains filtered or unexported fields
}

RunStatus encapsulates a cancellable Context for the purposes of determining whether a sub-process is running or to instruct it halt.

Example
package main

import (
	"context"
	"fmt"

	"github.com/aws/go-kafka-event-source/streams/sak"
)

func main() {
	parent := sak.NewRunStatus(context.Background()).WithValue("name", "parent")
	child1 := parent.Fork().WithValue("name", "child1") // will override "name" of parent
	child2 := parent.Fork()                             // will inherit "name" from parent

	child1.Halt() // child1 halts but parent continues to run

	fmt.Println(parent.Running())
	fmt.Println(child1.Running())
	fmt.Println(child2.Running())

	parent.Halt() // all RunStatus are halted

	fmt.Println(parent.Running())
	fmt.Println(child2.Running())
	fmt.Println(parent.Ctx().Value("name"))
	fmt.Println(child1.Ctx().Value("name"))
	fmt.Println(child2.Ctx().Value("name"))
}
Output:

true
false
true
false
false
parent
child1
parent

func NewRunStatus

func NewRunStatus(parent context.Context) RunStatus

Creates a RunStatus. If `parent` == nil, context.Background() is used.

func (RunStatus) Ctx

func (rs RunStatus) Ctx() context.Context

func (RunStatus) Done

func (rs RunStatus) Done() <-chan struct{}

Returns the RunStatus.Ctx().Done()

func (RunStatus) Err

func (rs RunStatus) Err() error

func (RunStatus) Fork

func (rs RunStatus) Fork() RunStatus

Creates a new child RunStatus, using the current RunStatus.Ctx() as a parent. The newly created RunStatus get's a new context.CancelFunc. Calling Halt on the returned RunStatus will not Halt the parent. The equivalent of calling:

NewRunStatus(rs.Ctx())

func (RunStatus) Halt

func (rs RunStatus) Halt()

func (RunStatus) Running

func (rs RunStatus) Running() bool

Returns true if the underlying Context has neither timed out or has been canceled.

func (RunStatus) WithValue added in v1.0.5

func (rs RunStatus) WithValue(key, value any) RunStatus

Creates a new RunStatus by adding key/value to the underlying Context. This is semantically different than Fork as the RunStatus returned here does not get a new context.CancelFunc, so calling Halt on the returned RunStatus will also halt the receiver.

type Signed

type Signed interface {
	~int | ~int16 | ~int32 | ~int64 | ~int8
}

type SignedNumber

type SignedNumber interface {
	Signed | Float
}

type Unsigned

type Unsigned interface {
	~uint | ~uint16 | ~uint32 | ~uint64 | uint8
}

Jump to

Keyboard shortcuts

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