class
Pf::Kit::HybridArray(T, N)
- Pf::Kit::HybridArray(T, N)
- Reference
- Object
Overview
A dynamic array which stores N x Ts in a fixed-size buffer (inline; most often allocated on the stack), and spills over to heap.
Inspiration: One of Walter Bright talks, at https://www.youtube.com/watch?v=_PB6Hdi4R7M&t=2606s
HybridArray is a reference type to limit hazardous usage by default. Note
that it is a hazardous type anyway, so you're probably better off using a normal
Array, unless you're working on the moderate to deep sub-microsecond time-scale.
The sub-microsecond time-scale starts to require things like these the lower you go. Consider HybridArray that odd-looking fish living at the bottom of the Mariana Trench, hyper-optimized for its particular niche but otherwise an abomination.
If you are using a HybridArray with a stack-allocated buffer, it makes little sense to not stack-allocate the HybridArray itself as well.
You can use the Pf::Kit.stack_array macro to allocate a hybrid array
and its buffer on the stack. See it for more info.
Included Modules
- Indexable::Mutable(T)
Defined in:
permafrost/kit/hybrid_array.crConstructors
-
.new(buffer : Pointer(T))
WARNING There are no checks making sure
N= buffer size (in fact, buffer has no known size or "size" at all at this point!)
Instance Method Summary
-
#<<(value : T) : self
Inserts value at the back of this array.
- #==(other : HybridArray(T, N)) : Bool
-
#clear : Nil
Removes all values from this array.
-
#concat(other : Indexable(T)) : self
Pushes all elements in other to this array.
- #inspect(io)
-
#pop : T
Removes and returns the last value of this array.
-
#pop? : T | Nil
Removes and returns the last value of this array.
- #pretty_print(pp) : Nil
-
#push(value : T) : self
Inserts value at the back of this array.
-
#reserve(newsize : Int32 | UInt32) : self
Increases the capacity of this array to a value greater than or equal to newsize.
-
#size : Int32
Returns the number of elements in this container.
-
#to_readonly_slice : Slice(T)
Returns a copy of this array's content as a read-only slice.
-
#to_s(io : IO) : Nil
Appends a short String representation of this object which includes its class name and its object address.
-
#to_slice : Slice(T)
Returns a copy of this array's content as a slice.
-
#to_unsafe_readonly_slice! : Slice(T)
Returns a slice referencing the content of this array.
-
#to_unsafe_slice! : Slice(T)
Returns a slice referencing the content of this array.
-
#unsafe_copy_to(target : Pointer(T)) : Nil
WARNING the destination must not overlap with this array's buffer (uses
Pointer#copy_to). -
#unsafe_fetch(index : Int) : T
Returns the element at the given index, without doing any bounds check.
-
#unsafe_put(index : Int, value : T) : Nil
Sets the element at the given index to value, without doing any bounds check.
-
#usize : UInt32
Returns the underlying
UInt32size of this array.
Instance methods inherited from module Enumerable(T)
to_pf_bidi
to_pf_bidi,
to_pf_map(& : T -> Tuple(K, V)) : Pf::Map(K, V) forall K, Vto_pf_map to_pf_map, to_pf_set : Pf::Set(T) to_pf_set, to_pf_uset32 : Pf::USet32 to_pf_uset32
Constructor Detail
WARNING There are no checks making sure N = buffer size (in fact, buffer
has no known size or "size" at all at this point!)
Instance Method Detail
Removes and returns the last value of this array. Raises IndexError if
this array is empty.
Removes and returns the last value of this array. Returns nil if
this array is empty.
Increases the capacity of this array to a value greater than or equal to newsize.
This applies to the spill part. If newsize is less than N, the inline part's capacity, this function does nothing. Ditto if the spill part's capacity is greater than or equal to capacity.
Returns the number of elements in this container.
Appends a short String representation of this object which includes its class name and its object address.
class Person
def initialize(@name : String, @age : Int32)
end
end
Person.new("John", 32).to_s # => #<Person:0x10a199f20>
Returns a slice referencing the content of this array.
See #to_unsafe_slice! for info on safety.
Returns a slice referencing the content of this array.
This overload is most beneficial when there is spillover. When there is none,
this overload is the same as calling #to_slice.
Since spillover reserves 1.5x more memory than strictly necessary, we can use that extra memory, when possible, to memmove, and then put the array's inline (e.g. stack-allocated) content in front. This overload does exactly that.
If we can't use the remaining memory (inline content doesn't fit in spillover), we reallocate, which means the GC may give us the same chunk of memory, but longer. Sometimes it will not.
WARNING This method alters this array's original content. You must not use the array after calling this method, as its spillover part is now referenced by others.
WARNING the destination must not overlap with this array's buffer (uses Pointer#copy_to).
WARNING no checks are done with respect to the size of target.
Returns the element at the given index, without doing any bounds check.
Indexable makes sure to invoke this method with index in 0...size,
so converting negative indices to positive ones is not needed here.
Clients never invoke this method directly. Instead, they access
elements with #[](index) and #[]?(index).
This method should only be directly invoked if you are absolutely sure the index is in bounds, to avoid a bounds check for a small boost of performance.
Sets the element at the given index to value, without doing any bounds check.
Indexable::Mutable makes sure to invoke this method with index in
0...size, so converting negative indices to positive ones is not needed
here.
Clients never invoke this method directly. Instead, they modify elements
with #[]=(index, value).
This method should only be directly invoked if you are absolutely sure the index is in bounds, to avoid a bounds check for a small boost of performance.