pslices

package
v0.4.170 Latest Latest
Warning

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

Go to latest
Published: May 11, 2024 License: ISC Imports: 10 Imported by: 2

Documentation

Overview

Package pslices provides somehat outdated slice functions such as ordered slices

Index

Constants

View Source
const (
	//   - [ZeroFillingShifter] provided as argument to [NewShifter] causes
	//     freed elements to be set to the T zero-value.
	//     This prevents temporary memory leaks when:
	//   - T contains pointers and
	//   - previously used T elements remain in the slice’s underlying array
	ZeroFillingShifter = true
)

Variables

This section is empty.

Functions

func ConvertSliceToInterface added in v0.4.29

func ConvertSliceToInterface[T, G any](structSlice []T) (interfaceSlice []G)

ConvertSliceToInterface converts a slice of a struct type to a slice of an interface type.

  • T is any type
  • G is an interface type that *T implements

If *T does not implement G: runtime panic

func IndexPartial added in v0.4.38

func IndexPartial(byts []byte, index int, key []byte) (newIndex int, notKnown bool)

IndexPartial returns scan-result in a byte-slice for a key byte-sequence, whether key was found or more bytes needs to be read to determine if key is present.

  • index is the first index to search at and it is checked against the length of byts
  • return value:
  • — notKnown: true, newIndex >= index: byts ended during a partial key match, newIndex is first byte of match
  • — notKnown: false, newIndex >= index: entire key was found at newIndex
  • — newIndex -1: no key sequence was found in byts
  • empty or nil key is found immediately, but only if index is less than length of byts
  • if byts is nil or empty, nothing is found
  • panic-free

func InsertOrdered

func InsertOrdered[E constraints.Ordered](slice0 []E, value E) (slice []E)

InsertOrdered inserts value into an ordered slice

  • duplicate values are allowed, new values are placed at the end
  • insert is O(log n)

func InsertOrderedFunc

func InsertOrderedFunc[E any](slice0 []E, value E, cmp func(a, b E) (result int)) (slice []E)

InsertOrderedFunc inserts a value into a slice making it ordered using a comparison function.

  • duplicate values are allowed, new values are placed at the end
  • insert is O(log n)
  • cmp function can be provided by E being a type with Cmp method.
  • cmp(a, b) is expected to return an integer comparing the two parameters: 0 if a == b, a negative number if a < b and a positive number if a > b

func NewOrdered added in v0.4.29

func NewOrdered[E constraints.Ordered]() (list parli.Ordered[E])

NewOrdered returns a slice ordered by value.

func NewOrderedAny

func NewOrderedAny[E any](cmp func(a, b E) (result int)) (list parli.Ordered[E])

NewOrderedAny creates a list ordered by a comparison function.

  • The cmp comparison function can be provided by E being pslices.Comparable, ie. a type having a Cmp method.
  • cmp(a, b) is expected to return an integer comparing the two parameters: 0 if a == b, a negative number if a < b and a positive number if a > b
  • duplicate values are allowed and inserted in order with later values last
  • if E is an interface-type and cmp is nil, every provided value must be checked to be comparable

func NewOrderedPointers

func NewOrderedPointers[E constraints.Ordered]() (list parli.OrderedPointers[E])

func ResolveSlice added in v0.4.29

func ResolveSlice[E any](slic []*E) (sList []E)

ResolveSlice removes one level of indirection from a slice of pointers.

func SetLength added in v0.4.48

func SetLength[E any](slicep *[]E, newLength int, noZero ...bool)

SetLength adjusts the lenght of *slicep extending with append if necessary.

  • slicep’s length is adjusted
  • if newLength > cap, slice may be reallocated

func StringifySlice added in v0.4.29

func StringifySlice[E any](slic []E) (sList []string)

StringifySlice returns the string representation of any slice

func TrimLeft added in v0.4.38

func TrimLeft[E any](slicep *[]E, count int, noZero ...bool)

TrimLeft removes count bytes from the start of slicep, copying remaining bytes to its beginning.

  • slicep’s length is adjusted
  • if count < 1 or slicep is empty or nil, nothing is done
  • if count >= len(slicep) slicep is emptied
  • no allocation or free is triggered
  • copy versus slice-away-and-alloc: if slice byte-length is 640 bytes or larger, use alloc
  • TrimLeft(&slice, 1) vs. slice = slice[1:]
  • one small slice alloc equals copy of 3,072 bytes: trimleft_bench_test.go
  • copy count of n elements one at a time is ∑n: [n(n+1)]/2
  • optimal strategy is slice-away slice[1:] and on append, try to avoid alloc by copy recuperating the obsoleted capacity

Types

type Ordered added in v0.4.29

type Ordered[E constraints.Ordered] struct {
	Slice[E]
}

Ordered is an ordered slice overwriting duplicates implementing [parl.Ordered][E any].

  • E must be a comparable and ordered type, ie. not slice func map.
  • Insert overwrites duplicates and is O(log n)
  • Delete removes the first occurrence O(log n)
  • For custom sort order or slice func map types, use NewOrderedAny

func (*Ordered[E]) Clone added in v0.4.29

func (o *Ordered[E]) Clone() (o2 parli.Ordered[E])

func (*Ordered[E]) Delete added in v0.4.29

func (o *Ordered[E]) Delete(element E)

Delete removes an element from an ordered slice.

  • if the element is not in the slice, the slice is not changed
  • is the slice has duplicates, the first occurrence is removed
  • O(log n)

func (*Ordered[E]) Index added in v0.4.29

func (o *Ordered[E]) Index(element E) (index int)

func (*Ordered[E]) Insert added in v0.4.29

func (o *Ordered[E]) Insert(element E)

Insert adds an element to an ordered slice.

  • Insert overwrites duplicates and is O(log n)

type OrderedAny

type OrderedAny[E any] struct {
	Slice[E] // Element() Length() List() Clear()
	// contains filtered or unexported fields
}

OrderedAny is a slice ordered by a function allowing duplicates. OrderedAny implements [parl.Ordered][E any].

  • cmp allows for custom ordering or ordering of slice map and function types
  • Use E as value for small-sized data or interface values.
  • Use E as a pointer for larger sized structs.
  • Duplicates are allowed, Inssert places duplicates at end
  • Insert and Delete O(log n)
  • cmp(a, b) is expected to return an integer comparing the two parameters: 0 if a == b, a negative number if a < b and a positive number if a > b

func (*OrderedAny[E]) Clone added in v0.4.29

func (o *OrderedAny[E]) Clone() (o2 parli.Ordered[E])

Length returns the number of elements

func (*OrderedAny[E]) Delete

func (o *OrderedAny[E]) Delete(element E)

Delete removes an element from the ordered slice.

  • if the element did not exist, the slice is not changed
  • if element exists in duplicates, a random element of those duplicates is removed
  • O(log n)

func (*OrderedAny[E]) Index added in v0.4.29

func (o *OrderedAny[E]) Index(element E) (index int)

func (*OrderedAny[E]) Insert

func (o *OrderedAny[E]) Insert(element E)

Insert adds a value to the ordered slice.

type OrderedPointers

type OrderedPointers[E constraints.Ordered] struct {
	OrderedAny[*E] // Element() Length() List() Clear() Insert() Delete() Index() Clone()
}

OrderedPointers is an ordered list of *E pointers sorted by the referenced values. OrderedPointers implements [parl.OrderedPointers][E any].

  • The OrderedPointers ordered list does not require a comparison function
  • E is used for large structs.
  • Insert overwrites duplicates.
  • for custom sort order, use NewOrderedAny

func (*OrderedPointers[E]) Cmp

func (o *OrderedPointers[E]) Cmp(a, b *E) (result int)

type Queue added in v0.4.43

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

func NewQueue added in v0.4.43

func NewQueue[T any]() (queue *Queue[T])

func (*Queue[T]) Add added in v0.4.43

func (q *Queue[T]) Add(value T)

func (*Queue[T]) AddSlice added in v0.4.43

func (q *Queue[T]) AddSlice(slice []T)

func (*Queue[T]) Remove added in v0.4.43

func (q *Queue[T]) Remove(value T, ok bool)

type RangeCh added in v0.4.58

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

RangeCh is a range-able channel based on a thread-safe slice

  • the slice is provided to the New function
  • each RangeCh has an internal thread that runs until:
  • — the slice is out of items
  • — Close is invoked
  • RangeCh.Ch() must be either read until close or RangeCh.Close must be invoked
  • Close discards items
  • it is unclear whether pairing an updatable slice with an unbuffered channel is useful
  • — unlike a buffered channel, RangeCh is unbound
  • — RangeCh costs 1 thread maintaining the unbuffered channel
  • — channels are somewhat inefficient by processing only one element at a time
  • — controlling allocations by processing single elements, slices of elements or slices of slices of elements
  • — RangeCh sends any available elements then closes the channel and exits

func NewRangeCh added in v0.4.58

func NewRangeCh[T any](tss *ThreadSafeSlice[T]) (rangeChan *RangeCh[T])

NewRangeCh returns a range-able channel based on a ThreadSafeSlice

  • the Ch channel must be either read until it closes or Close must be invoked
  • Ch is a channel that can be used in a Go for-range clause
  • for can range over: array slice string map or channel
  • the only dynamic range source is channel which costs a thread sending on and closing the channel

func (*RangeCh[T]) Ch added in v0.4.58

func (r *RangeCh[T]) Ch() (ch <-chan T)

Ch returns the range-able channel sending values, thread-safe

func (*RangeCh[T]) Close added in v0.4.58

func (r *RangeCh[T]) Close()

Close closes the ch channel, thread-safe, idempotent

  • Close may discard a pending item and causes the thread to stop reading from the slice
  • Close does not return until Ch is closed and the thread have exited

func (*RangeCh[T]) State added in v0.4.114

func (r *RangeCh[T]) State() (isCloseInvoked, isChClosed bool, exitCh <-chan struct{})

State returns RangeCh state - isCloseInvoked is true if RangeCh.Close has been invoked, but Close may not have completed - isChClosed means RangeCh.Ch has closed and resources are released - exitCh allows to wait for Close complete

type Shifter added in v0.4.143

type Shifter[T any] struct {
	// Slice contains current elements
	Slice []T
	// contains filtered or unexported fields
}

Shifter implements append filtered by a capacity check

  • this avoids unnecessary slice re-allocations for when a slice is used as a buffer:
  • — items are sliced off at the beginning and
  • — new items appended at the end

func NewShifter added in v0.4.143

func NewShifter[T any](slice []T, zeroFill ...bool) (shifter *Shifter[T])

NewShifter returns a slice container providing an Append that filters unnecessary allocations

  • if zeroFill is ZeroFillingShifter freed elements are set to zero-value
  • — this prevents temporary memory leaks when:
  • — elements contains pointers and
  • — previously used elements remain in the slice’s underlying array

func (*Shifter[T]) Append added in v0.4.143

func (s *Shifter[T]) Append(items ...T) (slice []T)

Append avoids unnecessary allocations if capacity is sufficient

type Slice added in v0.4.29

type Slice[E any] struct {
	// contains filtered or unexported fields
}

Slice is a base type for reusable slice implementations

  • super-types could implement Insert Delete Index
  • Length
  • Element single-element access
  • Slice multiple-element access
  • DeleteIndex delete elements
  • Clear Clone
  • List clone of n first items
  • Slice implements parl.Slice[E any].

func (*Slice[E]) Append added in v0.4.94

func (o *Slice[E]) Append(slice []E)

Append adds element at end

func (*Slice[E]) Cap added in v0.4.94

func (o *Slice[E]) Cap() (capacity int)

Cap returns slice capacity

func (*Slice[E]) Clear added in v0.4.29

func (o *Slice[E]) Clear()

Clear empties the ordered slice

func (*Slice[E]) Clone added in v0.4.94

func (o *Slice[E]) Clone() (clone *Slice[E])

Clone returns a shallow clone of the slice

func (*Slice[E]) DeleteIndex added in v0.4.94

func (o *Slice[E]) DeleteIndex(index0 int, index1 ...int)

DeleteIndex removes elements by index

  • index1 default is slice length

func (*Slice[E]) Element added in v0.4.29

func (o *Slice[E]) Element(index int) (element E)

Element returns element by index. if index is negative or the length of the slice or larger, the E zero-value is returned.

func (*Slice[E]) Length added in v0.4.29

func (o *Slice[E]) Length() (index int)

Length returns number of elements in the slice

func (*Slice[E]) List added in v0.4.29

func (o *Slice[E]) List(n ...int) (list []E)

List returns a clone of the n or all first slice elements

func (*Slice[E]) SetElement added in v0.4.94

func (o *Slice[E]) SetElement(index int, element E)

func (*Slice[E]) SubSlice added in v0.4.94

func (o *Slice[E]) SubSlice(index0, index1 int) (elements []E)

Slice returns a multiple-element sub-slice

type ThreadSafeSlice added in v0.4.58

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

ThreadSafeSlice provides certain thread-safe operations on a slice using sync.RWMutex mechanic

thread-safety challenges with a slice:

  • multiple slice instances may reference the same underlying array
  • append operation may change address of data and create multiple arrays
  • data race in reading and writing slice elements
  • multiple threads accessing a slice instance or their underlying array
  • due to slicing creating new memory-sharing slices, the slice value must be fully enclosed inside the type providing thread-safety
  • due to copy and append operations affecting multiple memory addresses, locking is required for thread-safety
  • maintaining authoritative slice-state during iteration

All slice operations:

  • len(slice)
  • append(slice, E...): may create new underlying array
  • cap(slice)
  • make([]E, n)
  • slice[:b]
  • slice[a:]
  • slice[a:b]
  • slice[:]
  • slice[a]
  • &slice[a]: address of slice element
  • &slice: address of slice
  • copy(slice, slice2)
  • slice literal
  • slice variable declaration
  • assignment of slice element

func NewThreadSafeSlice added in v0.4.58

func NewThreadSafeSlice[T any]() (threadSafeSlice *ThreadSafeSlice[T])

func (*ThreadSafeSlice[T]) Append added in v0.4.58

func (t *ThreadSafeSlice[T]) Append(element T)

func (*ThreadSafeSlice[T]) Clear added in v0.4.58

func (t *ThreadSafeSlice[T]) Clear()

func (*ThreadSafeSlice[T]) Get added in v0.4.58

func (t *ThreadSafeSlice[T]) Get(index int) (element T, hasValue bool)

func (*ThreadSafeSlice[T]) Length added in v0.4.58

func (t *ThreadSafeSlice[T]) Length() (length int)

func (*ThreadSafeSlice[T]) Put added in v0.4.58

func (t *ThreadSafeSlice[T]) Put(element T, index int) (success bool)

func (*ThreadSafeSlice[T]) SetLength added in v0.4.58

func (t *ThreadSafeSlice[T]) SetLength(newLength int)

func (*ThreadSafeSlice[T]) SliceClone added in v0.4.58

func (t *ThreadSafeSlice[T]) SliceClone() (clone []T)

func (*ThreadSafeSlice[T]) TrimLeft added in v0.4.58

func (t *ThreadSafeSlice[T]) TrimLeft(count int)

Jump to

Keyboard shortcuts

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