Skip to content

Commit

Permalink
BatchingSpliterator
Browse files Browse the repository at this point in the history
  • Loading branch information
pivovarit committed May 24, 2024
1 parent 76bb26d commit c7b027f
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 0 deletions.
Empty file.
64 changes: 64 additions & 0 deletions java-batching-spliterator/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.pivovarit</groupId>
<version>1.0</version>
<artifactId>java-batching-spliterator</artifactId>

<name>java-batching-spliterator</name>

<properties>
<jmh.version>1.35</jmh.version>
</properties>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>21</source>
<target>21</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<dependencies>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-surefire-provider</artifactId>
<version>1.1.0</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>

<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.22.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>${jmh.version}</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>${jmh.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package com.pivovarit.stream;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Spliterator;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Stream;

import static java.util.stream.Stream.empty;
import static java.util.stream.Stream.of;
import static java.util.stream.StreamSupport.stream;

/**
* @author Grzegorz Piwowarek
*/
final class BatchingSpliterator<T> implements Spliterator<List<T>> {

private final List<T> source;
private final int maxChunks;

private int chunks;
private int chunkSize;
private int consumed;

private BatchingSpliterator(List<T> list, int batches) {
if (batches < 1) {
throw new IllegalArgumentException("batches can't be lower than one");
}
source = list;
chunks = batches;
maxChunks = Math.min(list.size(), batches);
chunkSize = (int) Math.ceil(((double) source.size()) / batches);
}

static <T> Stream<List<T>> partitioned(List<T> list, int numberOfParts) {
int size = list.size();

if (size <= numberOfParts) {
return asSingletonListStream(list);
} else if (size == 0) {
return empty();
} else if (numberOfParts == 1) {
return of(list);
} else {
return stream(new BatchingSpliterator<>(list, numberOfParts), false);
}
}

private static <T> Stream<List<T>> asSingletonListStream(List<T> list) {
Stream.Builder<List<T>> acc = Stream.builder();
for (T t : list) {
acc.add(Collections.singletonList(t));
}
return acc.build();
}

static <T, R> Function<List<T>, List<R>> batching(Function<T, R> mapper) {
return batch -> {
List<R> list = new ArrayList<>(batch.size());
for (T t : batch) {
list.add(mapper.apply(t));
}
return list;
};
}

@Override
public boolean tryAdvance(Consumer<? super List<T>> action) {
if (consumed < source.size() && chunks != 0) {
List<T> batch = source.subList(consumed, consumed + chunkSize);
consumed += chunkSize;
chunkSize = (int) Math.ceil(((double) (source.size() - consumed)) / --chunks);
action.accept(batch);
return true;
} else {
return false;
}
}

@Override
public Spliterator<List<T>> trySplit() {
return null;
}

@Override
public long estimateSize() {
return maxChunks;
}

@Override
public int characteristics() {
return ORDERED | SIZED;
}
}
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<module>java-archunit</module>
<module>java-sealed-classes</module>
<module>java-completable-future-timeouts</module>
<module>java-batching-spliterator</module>
<module>java-event-sourcing</module>
<module>java-completable-future-allof</module>
<module>java-advanced-groupingby</module>
Expand Down

0 comments on commit c7b027f

Please sign in to comment.