All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.datakernel.async.IndexedCollector Maven / Gradle / Ivy

Go to download

Efficient non-blocking network and file I/O, for building Node.js-like client/server applications with high performance requirements. It is similar to Event Loop in Node.js. Although Eventloop runs in a single thread, multiple event loops can be launched at the same time allowing for efficient CPU usage.

There is a newer version: 3.1.0
Show newest version
/*
 * Copyright (C) 2015-2018 SoftIndex LLC.
 *
 * 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 io.datakernel.async;

import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.stream.Collector;

public interface IndexedCollector {
	A accumulator(int stages);

	void accumulate(A accumulator, int stageIndex, T stageResult);

	R finish(A accumulator);

	default R resultOf() {
		return resultOf(Collections.emptyList());
	}

	default R resultOf(T value1) {
		//noinspection ArraysAsListWithZeroOrOneArgument - using asList instead of singletonList() to allow mutability
		return resultOf(Arrays.asList(value1));
	}

	default R resultOf(T value1, T value2) {
		return resultOf(Arrays.asList(value1, value2));
	}

	default R resultOf(List values) {
		A accumulator = accumulator(values.size());
		for (int i = 0; i < values.size(); i++) {
			accumulate(accumulator, i, values.get(i));
		}
		return finish(accumulator);
	}

	static  IndexedCollector ofCollector(Collector collector) {
		return new IndexedCollector() {
			final BiConsumer accumulator = collector.accumulator();

			@Override
			public A accumulator(int stages) {
				return collector.supplier().get();
			}

			@Override
			public void accumulate(A accumulator, int stageIndex, T stageResult) {
				this.accumulator.accept(accumulator, stageResult);
			}

			@Override
			public R finish(A accumulator) {
				return collector.finisher().apply(accumulator);
			}
		};
	}

	IndexedCollector> TO_LIST = new IndexedCollector>() {
		@Override
		public Object[] accumulator(int stages) {
			return new Object[stages];
		}

		@Override
		public void accumulate(Object[] accumulator, int stageIndex, Object stageResult) {
			accumulator[stageIndex] = stageResult;
		}

		@SuppressWarnings("unchecked")
		@Override
		public List finish(Object[] accumulator) {
			return Arrays.asList(accumulator);
		}

		@Override
		public List resultOf() {
			return Collections.emptyList();
		}

		@Override
		public List resultOf(Object value1) {
			return Arrays.asList(value1);
		}

		@Override
		public List resultOf(Object value1, Object value2) {
			return Arrays.asList(value1, value2);
		}

		@SuppressWarnings("unchecked")
		@Override
		public List resultOf(List values) {
			return (List) values;
		}
	};

	@SuppressWarnings("unchecked")
	static  IndexedCollector> toList() {
		return (IndexedCollector) TO_LIST;
	}

	@SuppressWarnings("unchecked")
	static  IndexedCollector toArray(Class type) {
		return new IndexedCollector() {

			@Override
			public T[] accumulator(int stages) {
				return (T[]) Array.newInstance(type, stages);
			}

			@Override
			public void accumulate(T[] accumulator, int stageIndex, T stageResult) {
				accumulator[stageIndex] = stageResult;
			}

			@SuppressWarnings("unchecked")
			@Override
			public T[] finish(T[] accumulator) {
				return (T[]) accumulator;
			}

			@Override
			public T[] resultOf() {
				return (T[]) Array.newInstance(type, 0);
			}

			@Override
			public T[] resultOf(T value1) {
				T[] array = (T[]) Array.newInstance(type, 1);
				array[0] = (T) value1;
				return array;
			}

			@Override
			public T[] resultOf(T value1, T value2) {
				T[] array = (T[]) Array.newInstance(type, 2);
				array[0] = (T) value1;
				array[1] = (T) value2;
				return array;
			}

			@Override
			public T[] resultOf(List values) {
				return values.toArray(accumulator(0));
			}
		};
	}
}