package org.infinispan.stream.impl.local; import java.util.LongSummaryStatistics; import java.util.OptionalDouble; import java.util.OptionalLong; import java.util.PrimitiveIterator; import java.util.Set; import java.util.Spliterator; import java.util.concurrent.TimeUnit; import java.util.function.BiConsumer; import java.util.function.LongBinaryOperator; import java.util.function.LongConsumer; import java.util.function.LongFunction; import java.util.function.LongPredicate; import java.util.function.LongToDoubleFunction; import java.util.function.LongToIntFunction; import java.util.function.LongUnaryOperator; import java.util.function.ObjLongConsumer; import java.util.function.Supplier; import java.util.stream.LongStream; import org.infinispan.Cache; import org.infinispan.CacheStream; import org.infinispan.DoubleCacheStream; import org.infinispan.LongCacheStream; import org.infinispan.factories.ComponentRegistry; import org.infinispan.stream.CacheAware; import org.infinispan.stream.impl.intops.primitive.l.BoxedLongOperation; import org.infinispan.stream.impl.intops.primitive.l.DistinctLongOperation; import org.infinispan.stream.impl.intops.primitive.l.FilterLongOperation; import org.infinispan.stream.impl.intops.primitive.l.FlatMapLongOperation; import org.infinispan.stream.impl.intops.primitive.l.LimitLongOperation; import org.infinispan.stream.impl.intops.primitive.l.MapLongOperation; import org.infinispan.stream.impl.intops.primitive.l.MapToDoubleLongOperation; import org.infinispan.stream.impl.intops.primitive.l.MapToIntLongOperation; import org.infinispan.stream.impl.intops.primitive.l.MapToObjLongOperation; import org.infinispan.stream.impl.intops.primitive.l.PeekLongOperation; import org.infinispan.stream.impl.intops.primitive.l.SkipLongOperation; import org.infinispan.stream.impl.intops.primitive.l.SortedLongOperation; import org.infinispan.util.function.SerializableBiConsumer; import org.infinispan.util.function.SerializableLongBinaryOperator; import org.infinispan.util.function.SerializableLongConsumer; import org.infinispan.util.function.SerializableLongFunction; import org.infinispan.util.function.SerializableLongPredicate; import org.infinispan.util.function.SerializableLongToDoubleFunction; import org.infinispan.util.function.SerializableLongToIntFunction; import org.infinispan.util.function.SerializableLongUnaryOperator; import org.infinispan.util.function.SerializableObjLongConsumer; import org.infinispan.util.function.SerializableSupplier; /** * LongStream that wraps a given stream to allow for additional functionality such as injection of values into * various operations */ public class LocalLongCacheStream extends AbstractLocalCacheStream<Long, LongStream, LongCacheStream> implements LongCacheStream { public LocalLongCacheStream(StreamSupplier<Long, LongStream> streamSupplier, boolean parallel, ComponentRegistry registry) { super(streamSupplier, parallel, registry); } LocalLongCacheStream(AbstractLocalCacheStream<?, ?, ?> original) { super(original); } @Override public LocalLongCacheStream filter(LongPredicate predicate) { registry.wireDependencies(predicate); intermediateOperations.add(new FilterLongOperation<>(predicate)); return this; } @Override public LocalLongCacheStream filter(SerializableLongPredicate predicate) { return filter((LongPredicate) predicate); } @Override public LocalLongCacheStream map(LongUnaryOperator mapper) { registry.wireDependencies(mapper); intermediateOperations.add(new MapLongOperation(mapper)); return this; } @Override public LocalLongCacheStream map(SerializableLongUnaryOperator mapper) { return map((LongUnaryOperator) mapper); } @Override public <U> LocalCacheStream<U> mapToObj(LongFunction<? extends U> mapper) { registry.wireDependencies(mapper); intermediateOperations.add(new MapToObjLongOperation<>(mapper)); return new LocalCacheStream<U>(this); } @Override public <U> LocalCacheStream<U> mapToObj(SerializableLongFunction<? extends U> mapper) { return mapToObj((LongFunction<? extends U>) mapper); } @Override public LocalIntCacheStream mapToInt(LongToIntFunction mapper) { intermediateOperations.add(new MapToIntLongOperation(mapper)); return new LocalIntCacheStream(this); } @Override public LocalIntCacheStream mapToInt(SerializableLongToIntFunction mapper) { return mapToInt((LongToIntFunction) mapper); } @Override public LocalDoubleCacheStream mapToDouble(LongToDoubleFunction mapper) { intermediateOperations.add(new MapToDoubleLongOperation(mapper)); return new LocalDoubleCacheStream(this); } @Override public LocalDoubleCacheStream mapToDouble(SerializableLongToDoubleFunction mapper) { return mapToDouble((LongToDoubleFunction) mapper); } @Override public LocalLongCacheStream flatMap(LongFunction<? extends LongStream> mapper) { intermediateOperations.add(new FlatMapLongOperation(mapper)); return this; } @Override public LocalLongCacheStream flatMap(SerializableLongFunction<? extends LongStream> mapper) { return flatMap((LongFunction<? extends LongStream>) mapper); } @Override public LocalLongCacheStream distinct() { intermediateOperations.add(DistinctLongOperation.getInstance()); return this; } @Override public LocalLongCacheStream sorted() { intermediateOperations.add(SortedLongOperation.getInstance()); return this; } @Override public LocalLongCacheStream peek(LongConsumer action) { intermediateOperations.add(new PeekLongOperation(action)); return this; } @Override public LocalLongCacheStream peek(SerializableLongConsumer action) { return peek((LongConsumer) action); } @Override public LocalLongCacheStream limit(long maxSize) { intermediateOperations.add(new LimitLongOperation(maxSize)); return this; } @Override public LocalLongCacheStream skip(long n) { intermediateOperations.add(new SkipLongOperation(n)); return this; } @Override public void forEach(LongConsumer action) { injectCache(action); createStream().forEach(action); } @Override public void forEach(SerializableLongConsumer action) { forEach((LongConsumer) action); } @Override public <K, V> void forEach(ObjLongConsumer<Cache<K, V>> action) { Cache<K, V> cache = registry.getComponent(Cache.class); createStream().forEach(l -> action.accept(cache, l)); } @Override public <K, V> void forEach(SerializableObjLongConsumer<Cache<K, V>> action) { forEach((ObjLongConsumer<Cache<K, V>>) action); } @Override public void forEachOrdered(LongConsumer action) { injectCache(action); createStream().forEachOrdered(action); } /** * Method to inject a cache into a consumer. Note we only support this for the consumer at this * time. * @param cacheAware the instance that may be a {@link CacheAware} */ private void injectCache(LongConsumer cacheAware) { if (cacheAware instanceof CacheAware) { ((CacheAware) cacheAware).injectCache(registry.getComponent(Cache.class)); } } @Override public long[] toArray() { return createStream().toArray(); } @Override public long reduce(long identity, LongBinaryOperator op) { return createStream().reduce(identity, op); } @Override public long reduce(long identity, SerializableLongBinaryOperator op) { return reduce(identity, (LongBinaryOperator) op); } @Override public OptionalLong reduce(LongBinaryOperator op) { return createStream().reduce(op); } @Override public OptionalLong reduce(SerializableLongBinaryOperator op) { return reduce((LongBinaryOperator) op); } @Override public <R> R collect(Supplier<R> supplier, ObjLongConsumer<R> accumulator, BiConsumer<R, R> combiner) { return createStream().collect(supplier, accumulator, combiner); } @Override public <R> R collect(SerializableSupplier<R> supplier, SerializableObjLongConsumer<R> accumulator, SerializableBiConsumer<R, R> combiner) { return collect((Supplier<R>) supplier, accumulator, combiner); } @Override public long sum() { return createStream().sum(); } @Override public OptionalLong min() { return createStream().min(); } @Override public OptionalLong max() { return createStream().max(); } @Override public long count() { return createStream().count(); } @Override public OptionalDouble average() { return createStream().average(); } @Override public LongSummaryStatistics summaryStatistics() { return createStream().summaryStatistics(); } @Override public boolean anyMatch(LongPredicate predicate) { return createStream().anyMatch(predicate); } @Override public boolean anyMatch(SerializableLongPredicate predicate) { return anyMatch((LongPredicate) predicate); } @Override public boolean allMatch(LongPredicate predicate) { return createStream().allMatch(predicate); } @Override public boolean allMatch(SerializableLongPredicate predicate) { return allMatch((LongPredicate) predicate); } @Override public boolean noneMatch(LongPredicate predicate) { return createStream().noneMatch(predicate); } @Override public boolean noneMatch(SerializableLongPredicate predicate) { return noneMatch((LongPredicate) predicate); } @Override public OptionalLong findFirst() { return createStream().findFirst(); } @Override public OptionalLong findAny() { return createStream().findAny(); } @Override public DoubleCacheStream asDoubleStream() { return mapToDouble(l -> (double) l); } @Override public CacheStream<Long> boxed() { intermediateOperations.add(BoxedLongOperation.getInstance()); return new LocalCacheStream<>(this); } @Override public PrimitiveIterator.OfLong iterator() { return createStream().iterator(); } @Override public Spliterator.OfLong spliterator() { return createStream().spliterator(); } @Override public LocalLongCacheStream sequentialDistribution() { return this; } @Override public LocalLongCacheStream parallelDistribution() { return this; } @Override public LocalLongCacheStream filterKeySegments(Set<Integer> segments) { segmentsToFilter = segments; return this; } @Override public LocalLongCacheStream filterKeys(Set<?> keys) { keysToFilter = keys; return this; } @Override public LocalLongCacheStream distributedBatchSize(int batchSize) { // TODO: Does this change cache loader? return this; } @Override public LocalLongCacheStream segmentCompletionListener(SegmentCompletionListener listener) { // All segments are completed when the getStream() is completed so we don't track them return this; } @Override public LocalLongCacheStream disableRehashAware() { // Local long stream doesn't matter for rehash return this; } @Override public LocalLongCacheStream timeout(long timeout, TimeUnit unit) { // Timeout does nothing for a local long cache stream return this; } }