Documentation ¶
Overview ¶
Package pslices provides somehat outdated slice functions such as ordered slices
Index ¶
- Constants
- func ConvertSliceToInterface[T, G any](structSlice []T) (interfaceSlice []G)
- func IndexPartial(byts []byte, index int, key []byte) (newIndex int, notKnown bool)
- func InsertOrdered[E constraints.Ordered](slice0 []E, value E) (slice []E)
- func InsertOrderedFunc[E any](slice0 []E, value E, cmp func(a, b E) (result int)) (slice []E)
- func NewOrdered[E constraints.Ordered]() (list parli.Ordered[E])
- func NewOrderedAny[E any](cmp func(a, b E) (result int)) (list parli.Ordered[E])
- func NewOrderedPointers[E constraints.Ordered]() (list parli.OrderedPointers[E])
- func Offset[T any](slice0, slicedAway []T) (offset int, isValid bool)
- func ResolveSlice[E any](slic []*E) (sList []E)
- func SetLength[E any](slicep *[]E, newLength int, noZero ...bool)
- func SliceAwayAppend[T any](slicedAway, slice0 *[]T, values []T, noZeroOut ...bool)
- func SliceAwayAppend1[T any](slicedAway, slice0 *[]T, value T, noZeroOut ...bool)
- func StringifySlice[E any](slic []E) (sList []string)
- func TrimLeft[E any](slicep *[]E, count int, noZero ...bool)
- type Ordered
- type OrderedAny
- type OrderedPointers
- type Queue
- type RangeCh
- type Shifter
- type Slice
- func (o *Slice[E]) Append(slice []E)
- func (o *Slice[E]) Cap() (capacity int)
- func (o *Slice[E]) Clear()
- func (o *Slice[E]) Clone() (clone *Slice[E])
- func (o *Slice[E]) DeleteIndex(index0 int, index1 ...int)
- func (o *Slice[E]) Element(index int) (element E)
- func (o *Slice[E]) Length() (index int)
- func (o *Slice[E]) List(n ...int) (list []E)
- func (o *Slice[E]) SetElement(index int, element E)
- func (o *Slice[E]) SubSlice(index0, index1 int) (elements []E)
- type ThreadSafeSlice
- func (t *ThreadSafeSlice[T]) Append(element T)
- func (t *ThreadSafeSlice[T]) Clear()
- func (t *ThreadSafeSlice[T]) Get(index int) (element T, hasValue bool)
- func (t *ThreadSafeSlice[T]) Length() (length int)
- func (t *ThreadSafeSlice[T]) Put(element T, index int) (success bool)
- func (t *ThreadSafeSlice[T]) SetLength(newLength int)
- func (t *ThreadSafeSlice[T]) SliceClone() (clone []T)
- func (t *ThreadSafeSlice[T]) TrimLeft(count int)
Constants ¶
const DoZeroOut = false
SliceAwayAppend SliceAwayAppend1 do zero-out obsolete slice elements
- SetLength noZero
const NoZeroOut = true
SliceAwayAppend SliceAwayAppend1 do not zero-out obsolete slice elements
- SetLength noZero
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
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 ¶
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 ¶
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 Offset ¶ added in v0.4.172
Offset calculates how many items a slice-away slice is off from the initial slice
- slice0 is a slice containing the beginning of the underlying array
- slicedAway is a slice that has been sliced-off at the beginning
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
SetLength adjusts the lenght of *slicep extending with append if necessary
- slicep: pointer to slice whose length is adjusted
- newLength : the length of *slicep on return
- — if newLength > cap, slice may be reallocated
- noZero missing or DoZeroOut: elements becoming unused are set to zero-value
- — if element contain pointers, such elements are a temporary memory leak
- noZero NoZeroOut: no zero-out of elements
func SliceAwayAppend ¶ added in v0.4.172
SliceAwayAppend avoids allocations when a slice is sliced away from the beginning while being appended to at the end
- sliceAway: the slice of active values, sliced away and appended to
- slice0: the original sliceAway
- values: values that should be appended to sliceAway
- noZeroOut NoZeroOut: do not set unused element to zero-value. Slices retaining values containing pointers in unused elements is a temporary memory leak. Zero-out prevents this memory leak
- by storing the initial slice along with the slice-away slice, the initial slice can be retrieved which may avoid allocations
- SliceAwayAppend takes pointer to slice so it can update slicedAway and slice0
- There are three outcomes for a slice-away append:
- — 1 realloc: the result is larger than the underlying array
- — 2 append: appending fits slicedAway capacity
- — 3 copy: appending to SlicedAway fits the underlying array but not slicedAway capacity
func SliceAwayAppend1 ¶ added in v0.4.172
SliceAwayAppend1 avoids allocations when a slice is sliced away from the beginning and appended to at the end
- sliceAway: the slice of active values, sliced away and appended to
- slice0: the original sliceAway
- value: the value that should be appended to sliceAway
- by storing the initial slice along with the slice-away slice, the initial slice can be retrieved which may avoid allocations
- SliceAwayAppend avoid such allocations based on two pointers to slice
func StringifySlice ¶ added in v0.4.29
StringifySlice returns the string representation of any slice
func TrimLeft ¶ added in v0.4.38
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
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 }
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
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
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
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]) Clear ¶ added in v0.4.29
func (o *Slice[E]) Clear()
Clear empties the ordered slice
func (*Slice[E]) DeleteIndex ¶ added in v0.4.94
DeleteIndex removes elements by index
- index1 default is slice length
func (*Slice[E]) Element ¶ added in v0.4.29
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]) SetElement ¶ added in v0.4.94
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)