|
@@ -0,0 +1,126 @@
|
|
|
|
|
+package net.ranides.assira.collection.query.derived;
|
|
|
|
|
+
|
|
|
|
|
+import net.ranides.assira.collection.lists.ListUtils;
|
|
|
|
|
+import net.ranides.assira.collection.query.CQuery;
|
|
|
|
|
+import net.ranides.assira.collection.query.CQueryAbstract;
|
|
|
|
|
+import net.ranides.assira.collection.query.base.CQList;
|
|
|
|
|
+import net.ranides.assira.collection.query.support.BaseList;
|
|
|
|
|
+import net.ranides.assira.functional.Predicates;
|
|
|
|
|
+import net.ranides.assira.math.MathUtils;
|
|
|
|
|
+
|
|
|
|
|
+import java.util.Iterator;
|
|
|
|
|
+import java.util.List;
|
|
|
|
|
+import java.util.function.Supplier;
|
|
|
|
|
+import java.util.stream.Stream;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * Adapter query: it returns only specified fragment of source query.
|
|
|
|
|
+ * Used by {@link CQuery#slice(int, int)} operation.
|
|
|
|
|
+ *
|
|
|
|
|
+ * It reports all features supported by source except "each".
|
|
|
|
|
+ * Fast "each" is reported only, if selected slice does not skip more elements than "FAST_SKIP_LIMIT"
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ */
|
|
|
|
|
+public class CQChunk<T> extends CQueryAbstract<CQuery<T>> {
|
|
|
|
|
+
|
|
|
|
|
+ private final CQuery<T> source;
|
|
|
|
|
+ private final int chunk;
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Creates new chunked stream.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param source source
|
|
|
|
|
+ * @param size size
|
|
|
|
|
+ */
|
|
|
|
|
+ public CQChunk(CQuery<T> source, int size) {
|
|
|
|
|
+ this.source = source;
|
|
|
|
|
+ this.chunk = size;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Supplier<? extends RuntimeException> message() {
|
|
|
|
|
+ return source.message();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public CQuery<CQuery<T>> message(Supplier<? extends RuntimeException> message) {
|
|
|
|
|
+ source.message(message);
|
|
|
|
|
+ return this;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public boolean hasFastEach() {
|
|
|
|
|
+ return source.features().hasFastEach();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public boolean hasFastStream() {
|
|
|
|
|
+ return hasFastList();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public boolean hasFastIterator() {
|
|
|
|
|
+ return hasFastList();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public boolean hasFastLength() {
|
|
|
|
|
+ return source.features().hasFastLength() || source.features().hasFastList();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public boolean hasFastList() {
|
|
|
|
|
+ return source.features().hasFastList();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public boolean isParallel() {
|
|
|
|
|
+ return source.features().isParallel();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public CQuery<CQuery<T>> parallel() {
|
|
|
|
|
+ return isParallel() ? this : new CQChunk<>(source.parallel(), chunk);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public CQuery<CQuery<T>> sequential() {
|
|
|
|
|
+ return isParallel() ? new CQChunk<>(source.sequential(), chunk) : this;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Iterator<CQuery<T>> iterator() {
|
|
|
|
|
+ return list().iterator();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Stream<CQuery<T>> stream() {
|
|
|
|
|
+ return list().stream();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public List<CQuery<T>> list() {
|
|
|
|
|
+ if(hasFastList()) {
|
|
|
|
|
+ List<T> list = source.list();
|
|
|
|
|
+ int size = list.size();
|
|
|
|
|
+ return ListUtils.produce(MathUtils.divceil(size, chunk), i -> {
|
|
|
|
|
+ return new CQList<>(list.subList(i * chunk, Math.min(size, i * chunk + chunk)));
|
|
|
|
|
+ });
|
|
|
|
|
+ } else {
|
|
|
|
|
+ int max = size();
|
|
|
|
|
+ return ListUtils.produce(max, i -> source.slice(i*chunk, i*chunk+chunk));
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public int size() {
|
|
|
|
|
+ return MathUtils.divceil(source.size(), chunk);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public boolean whileEach(Predicates.EachPredicate<? super CQuery<T>> consumer) {
|
|
|
|
|
+ return BaseList.whileEach(this, consumer);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+}
|