ouroboros-network-0.1.0.1: A networking layer for the Ouroboros blockchain protocol
Safe Haskell None
Language Haskell2010

Ouroboros.Network.AnchoredSeq

Synopsis

AnchoredSeq type

data AnchoredSeq v a b where Source #

Generalisation of a Sequence with elements of type b with a custom measure v and an anchor a .

This type is strict in the elements, but not strict in the spine.

For example, an AnchoredSeq can represent a fragment of a chain containing blocks that is anchored at a certain point. It can also represent a history of ledger states with the anchor being the "immutable" ledger state.

NOTE: there might be multiple elements with the same measure, e.g., multiple blocks with the same WithOrigin SlotNo . That is why functions operating on an AnchoredSeq often take a predicate in addition to a measure. At most one element should satisfy that predicate, e.g., the block must have a certain hash. The behaviour is undefined when multiple elements satisfy the predicate.

Bundled Patterns

pattern Empty :: Anchorable v a b => a -> AnchoredSeq v a b

\( O(1) \) . Pattern for matching on or creating an empty AnchoredSeq . An empty sequence has/needs an anchor.

pattern (:>) :: Anchorable v a b => AnchoredSeq v a b -> b -> AnchoredSeq v a b infixl 5

\( O(1) \) . Add an element to the right of the anchored sequence.

pattern (:<) :: Anchorable v a b => b -> AnchoredSeq v a b -> AnchoredSeq v a b infixl 5

\( O(1) \) . View the first, leftmost block of the anchored sequence.

Note that the anchor shifts, i.e., the anchor of the second argument will correspond to the first argument.

This is only a view, not a constructor, as adding a block to the left would change the anchor of the sequence, but we have no information about the predecessor of the block we'd be prepending.

Anchorable

class ( Ord v, Bounded v) => Anchorable v a b | a -> v where Source #

Constaint needed to use an AnchoredSeq .

Methods

asAnchor :: b -> a Source #

b as anchor

getAnchorMeasure :: Proxy b -> a -> v Source #

Return the measure of an anchor

The advantage of this method over a Measured k a super-class constraint is that it doesn't inherit the Monoid k constraint, which is unused and often undesired.

Basic operations

head :: Anchorable v a b => AnchoredSeq v a b -> Either a b Source #

\( O(1) \) . When the sequence is empty, return the anchor, otherwise the most recently added element.

headAnchor :: forall v a b. Anchorable v a b => AnchoredSeq v a b -> a Source #

\( O(1) \) . The anchor corresponding to the most recently added element (i.e., the anchor that would be needed for a sequence starting after this). When the anchored sequence is empty, the anchor is returned.

last :: Anchorable v a b => AnchoredSeq v a b -> Either a b Source #

\( O(1) \) . When the sequence is empty, return the anchor, otherwise the leftmost element.

toNewestFirst :: AnchoredSeq v a b -> [b] Source #

\( O(n) \) . Return the elements in the AnchoredSeq in newest-to-oldest order.

toOldestFirst :: AnchoredSeq v a b -> [b] Source #

\( O(n) \) . Return the elements in the AnchoredSeq in oldest-to-newest order.

fromNewestFirst :: Anchorable v a b => a -> [b] -> AnchoredSeq v a b Source #

\( O(n) \) . Make an AnchoredSeq from a list of elements in newest-to-oldest order. The last element in the list will be the one after the given anchor.

fromOldestFirst :: Anchorable v a b => a -> [b] -> AnchoredSeq v a b Source #

\( O(n) \) . Make an AnchoredSeq from a list of elements in oldest-to-newest order. The first element in the list will be the one after the given anchor.

splitAt :: Anchorable v a b => Int -> AnchoredSeq v a b -> ( AnchoredSeq v a b, AnchoredSeq v a b) Source #

\( O(\log(\min(i,n-i)) \) . Split the AnchoredSeq at a given position.

POSTCONDITION: (before, after) = splitAt i s , then: * anchor before == anchor s * headAnchor before == anchor after * headAnchor after == headAnchor s * join before after == Just s

dropNewest :: Anchorable v a b => Int -> AnchoredSeq v a b -> AnchoredSeq v a b Source #

\( O(\log(\min(i,n-i)) \) . Drop the newest n elements from the AnchoredSeq . The anchor does not change.

takeOldest :: Anchorable v a b => Int -> AnchoredSeq v a b -> AnchoredSeq v a b Source #

\( O(\log(\min(i,n-i)) \) . Take the oldest n elements from the AnchoredSeq . The anchor does not change.

dropWhileNewest :: Anchorable v a b => (b -> Bool ) -> AnchoredSeq v a b -> AnchoredSeq v a b Source #

\( O(n) \) . Drop the newest elements that satisfy the predicate, keeping the remainder. The anchor does not change.

takeWhileOldest :: Anchorable v a b => (b -> Bool ) -> AnchoredSeq v a b -> AnchoredSeq v a b Source #

\( O(n) \) . Take the oldest elements that satisfy the predicate. The anchor does not change.

length :: Anchorable v a b => AnchoredSeq v a b -> Int Source #

\( O(1) \) . Return the number of elements. The anchor is not counted.

null :: AnchoredSeq v a b -> Bool Source #

\( O(1) \) . The anchor is not counted.

contains :: Anchorable v a b => v -> (b -> Bool ) -> AnchoredSeq v a b -> Bool Source #

\( O(\log(\min(i,n-i)) \) . Does the anchored sequence contain an element with the given measure that satisfies the predicate? The anchor is ignored.

withinBounds :: Anchorable v a b => v -> ( Either a b -> Bool ) -> AnchoredSeq v a b -> Bool Source #

\( O(\log(\min(i,n-i)) \) . Does the anchored sequence contain an element with the given measure that satisfies the predicate? The anchor is not ignored.

map :: Anchorable v2 a b2 => (b1 -> b2) -> AnchoredSeq v1 a b1 -> AnchoredSeq v2 a b2 Source #

\( O(n) \) . Maps over the elements and the elements.

bimap :: Anchorable v2 a2 b2 => (a1 -> a2) -> (b1 -> b2) -> AnchoredSeq v1 a1 b1 -> AnchoredSeq v2 a2 b2 Source #

\( O(n) \) . Maps over the elements.

mapPreservingMeasure :: (b1 -> b2) -> AnchoredSeq v a b1 -> AnchoredSeq v a b2 Source #

\( O(n) \) . Maps over the elements.

NOTE: the functions must preserve the measure.

More efficient than map

bimapPreservingMeasure :: (a1 -> a2) -> (b1 -> b2) -> AnchoredSeq v a1 b1 -> AnchoredSeq v a2 b2 Source #

\( O(n) \) . Maps over the anchor and the elements.

NOTE: the functions must preserve the measure.

More efficient than bimap

Special operations

rollback :: Anchorable v a b => v -> ( Either a b -> Bool ) -> AnchoredSeq v a b -> Maybe ( AnchoredSeq v a b) Source #

\( O(\log(\min(i,n-i)) \) . Roll back the anchored sequence such that its new head has the same measure as the given one and satisfies the predicate. When there is no such element or anchor, return Nothing .

isPrefixOf :: forall v a b. ( Eq a, Eq b) => AnchoredSeq v a b -> AnchoredSeq v a b -> Bool Source #

\( O(\max(n_1, n_2)) \) . Check whether the first anchored sequence is a prefix of the second. Comparisons are done based on the Eq instances.

The two AnchoredSeq s must have the same anchor, otherwise the first cannot be a prefix of the second.

isPrefixOfByMeasure :: forall v a b. Anchorable v a b => AnchoredSeq v a b -> AnchoredSeq v a b -> Bool Source #

\( O(\max(n_1, n_2)) \) . Check whether the first anchored sequence is a prefix of the second. Comparisons are done based on the measure.

The two AnchoredSeq s must have the same anchor, otherwise the first cannot be a prefix of the second.

lookupByMeasure :: Anchorable v a b => v -> AnchoredSeq v a b -> [b] Source #

\( O(\log(\min(i,n-i) + s) \) where s is the number of elements with the same measure. Return all elements in the anchored sequence with a measure ( k ) equal to the given one. The elements will be ordered from oldest to newest. Does not look at the anchor.

splitAfterMeasure :: Anchorable v a b => v -> ( Either a b -> Bool ) -> AnchoredSeq v a b -> Maybe ( AnchoredSeq v a b, AnchoredSeq v a b) Source #

\( O(\log(\min(i,n-i)) \) . Split the AnchoredSeq after an element or anchor with the given measure that satisfies the predicate. Return Nothing if there is no element or anchor with the given measure that satisfies the predicate.

If the given measure corresponds to the anchor and it satisfies the predicate, an empty sequence with the given anchor, and the original sequence are returned.

PRECONDITION: there can be multiple elements with the same measure, but there should be at most one element (or anchor) with the given measure satisfying the predicate.

POSTCONDITION: when Just (before, after) = splitAfterMeasure k f s , then: * anchor before == anchor s * headMeasure before == pt * anchorMeasure after == pt * headAnchor after == headAnchor s * join before after == Just s

splitBeforeMeasure :: Anchorable v a b => v -> (b -> Bool ) -> AnchoredSeq v a b -> Maybe ( AnchoredSeq v a b, AnchoredSeq v a b) Source #

\( O(\log(\min(i,n-i)) \) . Split the AnchoredSeq before an element with the given measure that satisfies the predicate. Return Nothing if the anchored sequence does not contain an element with the given measure that satisfies the predicate.

Unlike splitAfterMeasure we can't split before the anchor.

PRECONDITION: there can be multiple elements with the same measure, but there should be at most one element (or anchor) with the given measure satisfying the predicate.

POSTCONDITION: joining ( join ) the two anchored sequences gives back the original anchored sequence.

POSTCONDITION: the last element (oldest) in the second sequence has the given measure and satisfies the predicate.

join :: forall v a b. Anchorable v a b => ( Either a b -> a -> Bool ) -> AnchoredSeq v a b -> AnchoredSeq v a b -> Maybe ( AnchoredSeq v a b) Source #

\( O(\log(\min(n_1, n_2))) \) . Join two anchored sequences if the given function returns True for the head (newest element or anchor when empty) of the first sequence and the anchor of the second sequence, e.g., when they match.

The returned sequence will have the same anchor as the first sequence.

anchorNewest Source #

Arguments

:: forall v a b. Anchorable v a b
=> Word64
n
-> AnchoredSeq v a b
-> AnchoredSeq v a b

Take the n newest elements from the anchored sequence.

WARNING: this may change the anchor

When the anchored sequence contains fewer than n elements, the anchored sequence will be returned unmodified.

selectOffsets :: forall v a b. Anchorable v a b => [ Int ] -> AnchoredSeq v a b -> [ Either a b] Source #

\( O(o \log(\min(i,n-i))) \) . Select the elements and optionally the anchor based on the given offsets, starting from the head of the AnchoredSeq .

The list of offsets must be increasing monotonically (/strictly increasing is not required).

Note : offset n , where n equals the length of the AnchoredSeq , corresponds to the anchor. When the sequence is empty, offset 0 will thus correspond to the anchor.

filter Source #

Arguments

:: forall v a b. Anchorable v a b
=> (b -> Bool )

Filtering predicate

-> AnchoredSeq v a b
-> [ AnchoredSeq v a b]

\( O\(n\) ). Variation on filterWithStop without a stop condition.

filterWithStop Source #

Arguments

:: forall v a b. Anchorable v a b
=> (b -> Bool )

Filtering predicate

-> (b -> Bool )

Stop condition

-> AnchoredSeq v a b
-> [ AnchoredSeq v a b]

\( O(n + r * \log(\min(i,n-i)) \) where r is the number of consecutive ranges of elements to be included in the result.

Filter out elements that don't match the predicate.

As filtering removes elements the result is a sequence of disconnected sequences. The sequences are in the original order and are of maximum size.

As soon as the stop condition is true, the filtering stops and the remaining sequence (starting with the first element for which the stop condition is true) is the final sequence in the returned list.

The stop condition wins from the filtering predicate: if the stop condition is true for an element, but the filter predicate not, then the element still ends up in final sequence.

For example, given the sequence containing [0: 1, 2, 3, 4, 5, 6] where the anchor is separated from the elements by : :

filter         odd        -> [[0: 1], [2: 3], [4: 5]]
filterWithStop odd (>= 4) -> [[0: 1], [2: 3], [3: 4, 5, 6]]

Helper functions

Reference implementations for testing

filterWithStopSpec Source #

Arguments

:: forall v a b. Anchorable v a b
=> (b -> Bool )

Filtering predicate

-> (b -> Bool )

Stop condition

-> AnchoredSeq v a b
-> [ AnchoredSeq v a b]

\( O\(n\) ). Naive reference implementation of filterWithStop .

While the asymptotic complexity of this function is better than that of filterWithStop , the allocation cost is high. This function deconstructs and reconstructs the anchored sequence (until the stop condition is reached), even when no elements are removed.