Skip to content
gravittonPublic

About

Collection of extra packages that implement some useful features that are missing in the standard library

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

19 Commits

Folders and files

Repository files navigation

Gravitton x

Latest Stable Version Build Status Coverage Status Go Dev Reference Software License

Collection of extra packages that implement some useful features that are missing in the standard library


Features

  • Heap – generic min-heap over container/heap, with ordered and comparable constructors.
  • Queue – generic FIFO queue backed by a slice.
  • Slices – Map, plus Insert, Delete, and Contains on sorted slices.
  • Duration – time.Duration that marshals as "200ms" in JSON, TOML, and YAML.
  • Zero dependencies – only the standard library at runtime.

Installation

go get github.com/gravitton/x

Usage

Each package mirrors its standard-library namesake and is meant to be imported next to it.

Heap over any ordered type:

import "github.com/gravitton/x/container/heap"

h := heap.NewOrdered[int]()
h.Push(3)
h.Push(1)
h.Push(2)

h.Peek() // 1
h.Pop()  // 1
h.Len()  // 2

Heap over a custom type with a comparison function:

type task struct {
	name     string
	priority int
}

h := heap.New(func(a, b task) int {
	return cmp.Compare(a.priority, b.priority)
})

Priority queue with in-place updates. SetIndex records each element's position so Fix and Remove can find it:

type item struct {
	name     string
	priority int
	index    int
}

func (i *item) Compare(other *item) int {
	return cmp.Compare(i.priority, other.priority)
}

pq := heap.NewComparable[item]()
pq.SetIndex(func(i *item, index int) {
	i.index = index
})

orange := &item{name: "orange", priority: 1}
pq.Push(orange)
pq.Push(&item{name: "apple", priority: 2})

orange.priority = 5
pq.Fix(orange.index)

pq.Pop().name // "apple"

Queue:

import "github.com/gravitton/x/container/queue"

q := queue.New[string]()
q.Push("a")
q.Push("b")

q.Peek()  // "a"
q.Pop()   // "a"
q.Len()   // 1
q.Clear()

Slices:

import "github.com/gravitton/x/slices"

slices.Map([]float64{1.1, 2.6}, math.Round) // []float64{1, 3}
slices.Map([]int{1, 2}, strconv.Itoa)       // []string{"1", "2"}

s := []int{1, 3, 5}
s = slices.Insert(s, 4, true) // []int{1, 3, 4, 5}, sorted; true skips duplicates
s = slices.Delete(s, 3)       // []int{1, 4, 5}
slices.Contains(s, 4)         // true, by binary search

Duration in config files:

import xtime "github.com/gravitton/x/time"

type Config struct {
	Timeout xtime.Duration `json:"timeout"`
}

var cfg Config
json.Unmarshal([]byte(`{"timeout":"200ms"}`), &cfg)

cfg.Timeout.String()                      // "200ms"
cfg.Timeout.Equal(200 * time.Millisecond) // true

Full reference: pkg.go.dev.

Conventions

Heap: New takes a cmp.Compare-style function returning negative, zero, or positive. NewOrdered uses cmp.Compare for cmp.Ordered types. NewComparable works with pointer elements whose type implements Compare(*T) int, the cmp.Comparable constraint from this module. Pop and Peek panic on an empty heap; check Empty first.

Queue: Pop and Peek panic on an empty queue. Slice returns the backing slice, not a copy, so modifying it invalidates the queue. The same holds for Heap.Slice.

Sorted slices: Insert, Delete, and Contains assume the slice is already sorted in ascending order and use binary search. Results are unspecified for unsorted input.

Map: A nil input maps to a nil slice, so nil and empty stay distinguishable through a mapping.

Duration: Marshalling goes through encoding.TextMarshaler and encoding.TextUnmarshaler, so it works with encoding/json and any TOML or YAML library that honours those interfaces. Parsing accepts anything time.ParseDuration does.

Credits

License

The MIT License (MIT). Please see License File for more information.

About

Collection of extra packages that implement some useful features that are missing in the standard library

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Contributors

Languages