net.openhft.chronicle.wire.domestic.reduction.Reduction Maven / Gradle / Ivy
/*
* Copyright 2016-2022 chronicle.software
*
* https://chronicle.software
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.openhft.chronicle.wire.domestic.reduction;
import net.openhft.chronicle.core.annotation.NonNegative;
import net.openhft.chronicle.core.io.InvalidMarshallableException;
import net.openhft.chronicle.wire.ExcerptListener;
import net.openhft.chronicle.wire.MarshallableIn;
import net.openhft.chronicle.wire.Wire;
import net.openhft.chronicle.wire.domestic.extractor.DocumentExtractor;
import net.openhft.chronicle.wire.domestic.extractor.ToDoubleDocumentExtractor;
import net.openhft.chronicle.wire.domestic.extractor.ToLongDocumentExtractor;
import net.openhft.chronicle.wire.internal.reduction.ReductionUtil;
import org.jetbrains.annotations.NotNull;
import java.util.function.*;
import java.util.stream.Collector;
import static net.openhft.chronicle.core.util.ObjectUtils.requireNonNull;
/**
* This is the Reduction interface which extends ExcerptListener.
* It provides a means to consume excerpts from a given wire and apply reductions on them.
* The implementations of this interface should be thread-safe, especially if they are referenced as an {@link ExcerptListener}.
*/
public interface Reduction extends ExcerptListener {
/**
* Consumes an excerpt from the provided {@code wire} at the index at the provided {@code index}.
*
* If this method throws an Exception, it is relayed to the call site.
* Therefore, care should be taken to minimise the probability of throwing Exceptions.
*
* If this method is referenced as an {@link ExcerptListener} then the Reduction must be
* thread-safe.
**/
void onExcerpt(@NotNull Wire wire, @NonNegative long index) throws InvalidMarshallableException;
/**
* Returns a view of the underlying reduction.
*
* @return Reduction view.
*/
@NotNull
T reduction();
/**
* Accepts the input of the provided {@code tailer } and reduces (folds) the contents of it
* into this Reduction returning the last seen index or -1 if no index was seen.
*
* This method can be used to initialise a Reduction before appending new values.
*
* It is the responsibility of the caller to make sure no simultaneous appenders are using
* this Reduction during the entire fold operation.
*
* @param tailer to reduce (fold) from
* @return the last index seen or -1 if no index was seen
* @throws NullPointerException if the provided {@code tailer} is {@code null}
*/
default long accept(@NotNull final MarshallableIn tailer) throws InvalidMarshallableException {
requireNonNull(tailer);
return ReductionUtil.accept(tailer, this);
}
// Basic static constructors
/**
* Creates and returns a new {@code ReductionBuilder} that will use the provided
* {@code extractor} to extract elements of type {@code E}.
*
* This method initializes a generic reduction builder suitable for custom element types.
*
* @param the element type
* @param extractor the document extractor used to extract elements, must not be null
* @return a new {@code ReductionBuilder} instance
* @see LongReductionBuilder
* @see DoubleReductionBuilder
*/
static ReductionBuilder of(@NotNull final DocumentExtractor extractor) {
requireNonNull(extractor);
return new ReductionUtil.VanillaReductionBuilder<>(extractor);
}
/**
* Creates and returns a new {@code LongReductionBuilder} that will use the provided
* {@code extractor} to extract elements of type {@code long}.
*
* This method initializes a reduction builder specifically for handling long values.
*
* @param extractor the document extractor for long values, must not be null
* @return a new {@code LongReductionBuilder} instance
* @see #ofDouble(ToDoubleDocumentExtractor)
*/
static LongReductionBuilder ofLong(@NotNull final ToLongDocumentExtractor extractor) {
requireNonNull(extractor);
return new ReductionUtil.VanillaLongReductionBuilder(extractor);
}
/**
* Creates and returns a new {@code DoubleReductionBuilder} that will use the provided
* {@code extractor} to extract elements of type {@code double}.
*
* This method initializes a reduction builder specifically for handling double values.
*
* @param extractor the document extractor for double values, must not be null
* @return a new {@code DoubleReductionBuilder} instance
* @see #of(DocumentExtractor)
* @see #ofLong(ToLongDocumentExtractor)
*/
static DoubleReductionBuilder ofDouble(@NotNull final ToDoubleDocumentExtractor extractor) {
requireNonNull(extractor);
return new ReductionUtil.VanillaDoubleReductionBuilder(extractor);
}
/**
* ReductionBuilder is an interface that defines the contract for creating new Reductions using a specific collector.
* Implementations of this interface should cater to the specific type of element being reduced.
*/
interface ReductionBuilder {
/**
* Creates and returns a new Reduction of type R using the provided {@code collector}.
*
* The provided {@code collector } should be concurrent.
*
* @param collector to use (non-null)
* @param intermediate accumulation form
* @param Reduction type
* @return a new Reduction of type R
* @throws NullPointerException if the provided {@code collector} is {@code null}
*/
Reduction collecting(@NotNull final Collector collector);
}
/**
* LongReductionBuilder is an interface that defines the contract for creating Reductions specialized for handling long data types.
*/
interface LongReductionBuilder {
/**
* Creates and returns a new Reduction of type LongSupplier using the provided
* parameters.
*
* @param supplier to use (non-null) to create the internal state
* @param accumulator to use when merging long elements into the internal state
* @param finisher to use when extracting the result from the internal state
* @param intermediate accumulation form (must be concurrent)
* @return a new Reduction of type LongSupplier
* @throws NullPointerException if any of the provided parameters are {@code null}
*/
Reduction reducing(@NotNull final Supplier supplier,
@NotNull final ObjLongConsumer accumulator,
@NotNull final ToLongFunction finisher);
}
/**
* DoubleReductionBuilder is an interface that defines the contract for creating Reductions specialized for handling double data types.
*/
interface DoubleReductionBuilder {
/**
* Creates and returns a new Reduction of type DoubleSupplier using the provided
* parameters.
*
* @param supplier to use (non-null) to create the internal state
* @param accumulator to use when merging double elements into the internal state
* @param finisher to use when extracting the result from the internal state
* @param intermediate accumulation form (must be concurrent)
* @return a new Reduction of type DoubleSupplier
* @throws NullPointerException if any of the provided parameters are {@code null}
*/
Reduction reducing(@NotNull final Supplier supplier,
@NotNull final ObjDoubleConsumer accumulator,
@NotNull final ToDoubleFunction finisher);
}
}