├── .gitattributes ├── .github ├── dependabot.yml └── workflows │ ├── build_pr.yml │ └── gradle-wrapper-validation.yml ├── .gitignore ├── .travis.yml ├── HEADER ├── LICENSE ├── README.md ├── build.gradle ├── gradle.properties ├── gradle ├── javadocStyleSheet.css ├── maven.gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── pmd.xml ├── settings.gradle └── src ├── jmh └── java │ └── hu │ └── akarnokd │ └── assyncenum │ └── AsyncRangePerf.java ├── main └── java │ └── hu │ └── akarnokd │ └── asyncenum │ ├── AsyncBlockingFirst.java │ ├── AsyncBlockingIterable.java │ ├── AsyncBlockingLast.java │ ├── AsyncCache.java │ ├── AsyncCollect.java │ ├── AsyncCollectWith.java │ ├── AsyncCompletableFuture.java │ ├── AsyncConcatArray.java │ ├── AsyncConcatMap.java │ ├── AsyncCreate.java │ ├── AsyncDefer.java │ ├── AsyncDistinct.java │ ├── AsyncDistinctUntilChanged.java │ ├── AsyncDoFinally.java │ ├── AsyncDoOn.java │ ├── AsyncDoOnCancel.java │ ├── AsyncEmitter.java │ ├── AsyncEmpty.java │ ├── AsyncEnumerable.java │ ├── AsyncEnumerator.java │ ├── AsyncEnumeratorHelper.java │ ├── AsyncError.java │ ├── AsyncFilter.java │ ├── AsyncFirst.java │ ├── AsyncFlatMap.java │ ├── AsyncForEach.java │ ├── AsyncFromArray.java │ ├── AsyncFromCallable.java │ ├── AsyncFromCharSequence.java │ ├── AsyncFromCompletionStage.java │ ├── AsyncFromFlowPublisher.java │ ├── AsyncFromIterable.java │ ├── AsyncFromStream.java │ ├── AsyncGenerate.java │ ├── AsyncGroupBy.java │ ├── AsyncIgnoreElements.java │ ├── AsyncInterval.java │ ├── AsyncJust.java │ ├── AsyncLast.java │ ├── AsyncMap.java │ ├── AsyncMax.java │ ├── AsyncNever.java │ ├── AsyncObserveOn.java │ ├── AsyncOnErrorResume.java │ ├── AsyncPublish.java │ ├── AsyncRange.java │ ├── AsyncReduce.java │ ├── AsyncReduceWith.java │ ├── AsyncRepeat.java │ ├── AsyncRepeatCallable.java │ ├── AsyncRepeatItem.java │ ├── AsyncRepeatWhen.java │ ├── AsyncRetry.java │ ├── AsyncRetryWhen.java │ ├── AsyncSkip.java │ ├── AsyncSkipLast.java │ ├── AsyncSkipWhile.java │ ├── AsyncSubscribeOn.java │ ├── AsyncSumInt.java │ ├── AsyncSumLong.java │ ├── AsyncSwitchIfEmpty.java │ ├── AsyncTake.java │ ├── AsyncTakeLast.java │ ├── AsyncTakeUntil.java │ ├── AsyncTakeUntilPredicate.java │ ├── AsyncTakeWhile.java │ ├── AsyncTimeoutTimed.java │ ├── AsyncTimer.java │ ├── AsyncToFlowPublisher.java │ ├── AsyncUsing.java │ ├── AsyncZipArray.java │ ├── CancelledEnumeratorException.java │ ├── GroupedAsyncEnumerable.java │ ├── SyncEmitter.java │ └── ThrowableHelper.java └── test └── java └── hu └── akarnokd └── asyncenum ├── AsyncBlockingFirstOptionalTest.java ├── AsyncBlockingFirstTest.java ├── AsyncBlockingIterableTest.java ├── AsyncBlockingLastOptionalTest.java ├── AsyncBlockingLastTest.java ├── AsyncCacheTest.java ├── AsyncCharactersTest.java ├── AsyncCollectTest.java ├── AsyncCompletionStageTest.java ├── AsyncComposeTest.java ├── AsyncConcatArrayTest.java ├── AsyncConcataMapTest.java ├── AsyncCreateTest.java ├── AsyncDistinctTest.java ├── AsyncDistinctUntilChangedTest.java ├── AsyncDoOnCancelTest.java ├── AsyncDoOnXTest.java ├── AsyncEmptyTest.java ├── AsyncEnumeratorHelperTest.java ├── AsyncErrorTest.java ├── AsyncFilterTest.java ├── AsyncFirstTest.java ├── AsyncFlatMapTest.java ├── AsyncForEachTest.java ├── AsyncFromArrayTest.java ├── AsyncFromCallableTest.java ├── AsyncFromFlowPublisherTest.java ├── AsyncFromIterableTest.java ├── AsyncFromStreamTest.java ├── AsyncGenerateTest.java ├── AsyncGroupByTest.java ├── AsyncIgnoreElementsTest.java ├── AsyncIntervalTest.java ├── AsyncLastTest.java ├── AsyncMathOperatorsTest.java ├── AsyncMergeTest.java ├── AsyncNeverTest.java ├── AsyncObserveOnTest.java ├── AsyncOnErrorResumeTest.java ├── AsyncPublishTest.java ├── AsyncRangeTest.java ├── AsyncReduceTest.java ├── AsyncReduceWithTest.java ├── AsyncRepeatCallableTest.java ├── AsyncRepeatItemTest.java ├── AsyncRepeatTest.java ├── AsyncRepeatWhenTest.java ├── AsyncRetryTest.java ├── AsyncRetryWhenTest.java ├── AsyncSkipLastTest.java ├── AsyncSkipTest.java ├── AsyncSkipWhileTest.java ├── AsyncSubscribeOnTest.java ├── AsyncSwitchIfEmptyTest.java ├── AsyncTakeLastTest.java ├── AsyncTakeTest.java ├── AsyncTakeUntilPredicateTest.java ├── AsyncTakeUntilTest.java ├── AsyncTakeWhileTest.java ├── AsyncTimeoutTest.java ├── AsyncTimerTest.java ├── AsyncToFlowPublisherTckTest.java ├── AsyncToFlowPublisherTest.java ├── AsyncUsingTest.java ├── AsyncZipArrayTest.java ├── TestHelper.java └── ThrowableHelperTest.java /.gitattributes: -------------------------------------------------------------------------------- 1 | # Set default behaviour, in case users don't have core.autocrlf set. 2 | * text=auto 3 | 4 | # Explicitly declare text files we want to always be normalized and converted 5 | # to native line endings on checkout. 6 | *.java text 7 | *.groovy text 8 | *.scala text 9 | *.clj text 10 | *.txt text 11 | *.md text 12 | 13 | # Denote all files that are truly binary and should not be modified. 14 | *.png binary 15 | *.jpg binary 16 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: gradle 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "04:00" 8 | open-pull-requests-limit: 20 9 | ignore: 10 | - dependency-name: com.vanniktech:gradle-maven-publish-plugin 11 | versions: 12 | - 0.14.0 13 | - 0.14.1 14 | - 0.14.2 15 | - 0.15.0 16 | -------------------------------------------------------------------------------- /.github/workflows/build_pr.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Gradle 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle 3 | 4 | name: Java CI with Gradle 5 | 6 | on: 7 | push: 8 | branches: [ master ] 9 | pull_request: 10 | branches: [ master ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v2 19 | - name: Set up JDK 11 20 | uses: actions/setup-java@v1 21 | with: 22 | java-version: 11 23 | - name: Cache Gradle packages 24 | uses: actions/cache@v2 25 | with: 26 | path: ~/.gradle/caches 27 | key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} 28 | restore-keys: ${{ runner.os }}-gradle 29 | - name: Grant execute permission for gradlew 30 | run: chmod +x gradlew 31 | - name: Build with Gradle 32 | run: ./gradlew build --stacktrace 33 | - name: Upload to Codecov 34 | uses: codecov/codecov-action@v1 35 | -------------------------------------------------------------------------------- /.github/workflows/gradle-wrapper-validation.yml: -------------------------------------------------------------------------------- 1 | name: "Validate Gradle Wrapper" 2 | on: [push, pull_request] 3 | 4 | jobs: 5 | validation: 6 | name: "Validation" 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v2 10 | - uses: gradle/wrapper-validation-action@v1 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | 3 | # Package Files # 4 | *.jar 5 | *.war 6 | *.ear 7 | /build/ 8 | 9 | .gradle 10 | .m2 11 | /.nb-gradle/ 12 | /bin/ 13 | .settings/ 14 | .nb-gradle-properties 15 | .classpath 16 | .project 17 | .settings 18 | .metadata 19 | .checkstyle 20 | bin/ 21 | !/gradle/wrapper/gradle-wrapper.jar 22 | .pmd 23 | .ruleset 24 | local.properties 25 | .idea 26 | *.iml -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | 3 | sudo: required 4 | dist: trusty 5 | group: edge 6 | jdk: oraclejdk9 7 | #addons: 8 | # apt: 9 | # packages: 10 | # - oracle-java9-installer 11 | 12 | 13 | #jdk: 14 | # - oraclejdk9 15 | 16 | before_install: 17 | - chmod +x gradlew 18 | - mkdir -p ~/.gradle && echo "org.gradle.daemon=false" >> ~/.gradle/gradle.properties 19 | - export GRADLE_OPTS=-Xmx1024m 20 | # From https://github.com/reactive-streams/reactive-streams-jvm/pull/383 21 | # - cd ~ 22 | # - wget http://download.java.net/java/jdk9/archive/181/binaries/jdk-9+181_linux-x64_bin.tar.gz 23 | # - tar -xzf jdk-9+181_linux-x64_bin.tar.gz 24 | # - export JAVA_HOME=~/jdk-9 25 | # - PATH=$JAVA_HOME/bin:$PATH 26 | # - cd - 27 | 28 | after_success: 29 | - bash <(curl -s https://codecov.io/bash) 30 | 31 | # cache between builds 32 | cache: 33 | directories: 34 | - $HOME/.m2 35 | - $HOME/.gradle 36 | -------------------------------------------------------------------------------- /HEADER: -------------------------------------------------------------------------------- 1 | Copyright ${year} David Karnok 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-XX:+IgnoreUnrecognizedVMOptions --permit-illegal-access --show-version 2 | GROUP=com.github.akarnokd 3 | VERSION_NAME=0.6.0 4 | version=0.6.0 5 | 6 | POM_ARTIFACT_ID=async-enumerable 7 | POM_NAME=Prototype Java 9 library based on the asynchronous enumerable concept (where moveNext() returns a task to compose over). 8 | POM_PACKAGING=jar 9 | 10 | POM_DESCRIPTION=Prototype Java 9 library based on the asynchronous enumerable concept (where moveNext() returns a task to compose over). 11 | POM_INCEPTION_YEAR=2016 12 | 13 | POM_URL=https://github.com/akarnokd/async-enumerable 14 | POM_SCM_URL=https://github.com/akarnokd/async-enumerable 15 | POM_SCM_CONNECTION=scm:git:git://github.com/akarnokd/async-enumerable.git 16 | POM_SCM_DEV_CONNECTION=scm:git:ssh://git@github.com/akarnokd/async-enumerable.git 17 | 18 | POM_LICENCE_NAME=The Apache Software License, Version 2.0 19 | POM_LICENCE_URL=https://www.apache.org/licenses/LICENSE-2.0.txt 20 | POM_LICENCE_DIST=repo 21 | 22 | POM_DEVELOPER_ID=akarnokd 23 | POM_DEVELOPER_NAME=David Karnok 24 | -------------------------------------------------------------------------------- /gradle/javadocStyleSheet.css: -------------------------------------------------------------------------------- 1 | /* # originally from http://sensemaya.org/files/stylesheet.css and then modified */ 2 | /* # http://sensemaya.org/maya/2009/07/10/making-javadoc-more-legible / 3 | 4 | /* Javadoc style sheet */ 5 | 6 | /* Define colors, fonts and other style attributes here to override the defaults */ 7 | 8 | /* Page background color */ 9 | body { background-color: #FFFFFF; color:#333; font-size: 100%; } 10 | 11 | body { font-size: 0.875em; line-height: 1.286em; font-family: "Helvetica", "Arial", sans-serif; } 12 | 13 | code { color: #777; line-height: 1.286em; font-family: "Consolas", "Lucida Console", "Droid Sans Mono", "Andale Mono", "Monaco", "Lucida Sans Typewriter"; } 14 | 15 | a { text-decoration: none; color: #16569A; /* also try #2E85ED, #0033FF, #6C93C6, #1D7BBE, #1D8DD2 */ } 16 | a:hover { text-decoration: underline; } 17 | 18 | 19 | table[border="1"] { border: 1px solid #ddd; } 20 | table[border="1"] td, table[border="1"] th { border: 1px solid #ddd; } 21 | table[cellpadding="3"] td { padding: 0.5em; } 22 | 23 | font[size="-1"] { font-size: 0.85em; line-height: 1.5em; } 24 | font[size="-2"] { font-size: 0.8em; } 25 | font[size="+2"] { font-size: 1.4em; line-height: 1.3em; padding: 0.4em 0; } 26 | 27 | /* Headings */ 28 | h1 { font-size: 1.5em; line-height: 1.286em;} 29 | h2.title { color: #c81f08; } 30 | 31 | /* Table colors */ 32 | .TableHeadingColor { background: #ccc; color:#444; } /* Dark mauve */ 33 | .TableSubHeadingColor { background: #ddd; color:#444; } /* Light mauve */ 34 | .TableRowColor { background: #FFFFFF; color:#666; font-size: 0.95em; } /* White */ 35 | .TableRowColor code { color:#000; } /* White */ 36 | 37 | /* Font used in left-hand frame lists */ 38 | .FrameTitleFont { font-size: 100%; } 39 | .FrameHeadingFont { font-size: 90%; } 40 | .FrameItemFont { font-size: 0.9em; line-height: 1.3em; 41 | } 42 | /* Java Interfaces */ 43 | .FrameItemFont a i { 44 | font-style: normal; color: #16569A; 45 | } 46 | .FrameItemFont a:hover i { 47 | text-decoration: underline; 48 | } 49 | 50 | 51 | /* Navigation bar fonts and colors */ 52 | .NavBarCell1 { background-color:#E0E6DF; } /* Light mauve */ 53 | .NavBarCell1Rev { background-color:#16569A; color:#FFFFFF} /* Dark Blue */ 54 | .NavBarFont1 { } 55 | .NavBarFont1Rev { color:#FFFFFF; } 56 | 57 | .NavBarCell2 { background-color:#FFFFFF; color:#000000} 58 | .NavBarCell3 { background-color:#FFFFFF; color:#000000} 59 | 60 | -------------------------------------------------------------------------------- /gradle/maven.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'maven' // Java plugin has to have been already applied for the conf2scope mappings to work 2 | apply plugin: 'signing' 3 | 4 | project.status = 'release' 5 | 6 | signing { 7 | required { gradle.taskGraph.hasTask(uploadMavenCentral) } 8 | sign configurations.archives 9 | } 10 | 11 | /** 12 | * Publishing to Maven Central example provided from http://jedicoder.blogspot.com/2011/11/automated-gradle-project-deployment-to.html 13 | * artifactory will execute uploadArchives to force generation of ivy.xml, and we don't want that to trigger an upload to maven 14 | * central, so using custom upload task. 15 | */ 16 | task uploadMavenCentral(type:Upload, dependsOn: signArchives) { 17 | configuration = configurations.archives 18 | onlyIf { ['release', 'snapshot'].contains(project.status) } 19 | repositories.mavenDeployer { 20 | beforeDeployment { signing.signPom(it) } 21 | 22 | // To test deployment locally, use the following instead of oss.sonatype.org 23 | //repository(url: "file://localhost/${rootProject.rootDir}/repo") 24 | 25 | def sonatypeUsername = rootProject.hasProperty('sonatypeUsername')?rootProject.sonatypeUsername:'' 26 | def sonatypePassword = rootProject.hasProperty('sonatypePassword')?rootProject.sonatypePassword:'' 27 | 28 | repository(url: 'https://oss.sonatype.org/service/local/staging/deploy/maven2') { 29 | authentication(userName: sonatypeUsername, password: sonatypePassword) 30 | } 31 | 32 | snapshotRepository(url: 'https://oss.sonatype.org/content/repositories/snapshots/') { 33 | authentication(userName: sonatypeUsername, password: sonatypePassword) 34 | } 35 | 36 | // Prevent datastamp from being appending to artifacts during deployment 37 | uniqueVersion = false 38 | 39 | // Closure to configure all the POM with extra info, common to all projects 40 | pom.project { 41 | name "${project.name}" 42 | description "${project.name} developed by David Karnok" 43 | developers { 44 | developer { 45 | id 'akarnokd' 46 | name 'David Karnok' 47 | email 'akarnokd@gmail.com' 48 | } 49 | } 50 | licenses { 51 | license { 52 | name 'The Apache Software License, Version 2.0' 53 | url 'http://www.apache.org/licenses/LICENSE-2.0.txt' 54 | distribution 'repo' 55 | } 56 | } 57 | url "https://github.com/akarnokd/${rootProject.githubProjectName}" 58 | scm { 59 | connection "scm:git:git@github.com:akarnokd/${rootProject.githubProjectName}.git" 60 | url "scm:git:git@github.com:akarnokd/${rootProject.githubProjectName}.git" 61 | developerConnection "scm:git:git@github.com:akarnokd/${rootProject.githubProjectName}.git" 62 | } 63 | issueManagement { 64 | system 'github' 65 | url "https://github.com/akarnokd/${rootProject.githubProjectName}/issues" 66 | } 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akarnokd/async-enumerable/04e1b6ce2f9c11e3ab35a0bdb9ff931bd68ceee6/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.0-bin.zip 6 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'async-enumerable' 2 | -------------------------------------------------------------------------------- /src/jmh/java/hu/akarnokd/assyncenum/AsyncRangePerf.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.assyncenum; 18 | 19 | import hu.akarnokd.asyncenum.*; 20 | import org.openjdk.jmh.annotations.*; 21 | import org.openjdk.jmh.infra.Blackhole; 22 | 23 | import java.util.concurrent.TimeUnit; 24 | import java.util.concurrent.atomic.AtomicInteger; 25 | import java.util.function.BiConsumer; 26 | 27 | @BenchmarkMode(Mode.Throughput) 28 | @Warmup(iterations = 5) 29 | @Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) 30 | @OutputTimeUnit(TimeUnit.SECONDS) 31 | @Fork(value = 1) 32 | @State(Scope.Thread) 33 | public class AsyncRangePerf extends AtomicInteger implements BiConsumer { 34 | 35 | @Param({"1", "10", "100", "1000", "10000", "100000", "1000000"}) 36 | int count; 37 | 38 | AsyncEnumerable range; 39 | 40 | AsyncEnumerator en; 41 | 42 | Blackhole bh; 43 | 44 | @Setup 45 | public void setup(Blackhole bh) { 46 | range = AsyncEnumerable.range(1, count); 47 | this.bh = bh; 48 | } 49 | 50 | @Benchmark 51 | public void range() { 52 | en = range.enumerator(); 53 | consume(); 54 | } 55 | 56 | void consume() { 57 | if (getAndIncrement() == 0) { 58 | do { 59 | en.moveNext().whenComplete(this); 60 | } while (decrementAndGet() != 0); 61 | } 62 | } 63 | 64 | @Override 65 | public void accept(Boolean aBoolean, Throwable throwable) { 66 | if (throwable != null) { 67 | bh.consume(throwable); 68 | return; 69 | } 70 | 71 | if (aBoolean) { 72 | bh.consume(en.current()); 73 | consume(); 74 | } else { 75 | bh.consume(false); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncBlockingFirst.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.*; 20 | import java.util.concurrent.ExecutionException; 21 | 22 | final class AsyncBlockingFirst { 23 | 24 | private AsyncBlockingFirst() { 25 | throw new IllegalStateException("No instances!"); 26 | } 27 | 28 | public static T blockingFirst(AsyncEnumerator source) { 29 | try { 30 | Boolean result = source.moveNext().toCompletableFuture().get(); 31 | if (result) { 32 | T r = source.current(); 33 | source.cancel(); 34 | return r; 35 | } 36 | throw new NoSuchElementException(); 37 | } catch (InterruptedException ex) { 38 | source.cancel(); 39 | throw new RuntimeException(ex); 40 | } catch (ExecutionException ex) { 41 | throw ThrowableHelper.wrapOrThrow(ex.getCause()); 42 | } 43 | } 44 | 45 | public static Optional blockingFirstOptional(AsyncEnumerator source) { 46 | try { 47 | Boolean result = source.moveNext().toCompletableFuture().get(); 48 | if (result) { 49 | T r = source.current(); 50 | source.cancel(); 51 | return Optional.ofNullable(r); 52 | } 53 | return Optional.empty(); 54 | } catch (InterruptedException ex) { 55 | source.cancel(); 56 | throw new RuntimeException(ex); 57 | } catch (ExecutionException ex) { 58 | throw ThrowableHelper.wrapOrThrow(ex.getCause()); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncBlockingIterable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.*; 20 | import java.util.concurrent.ExecutionException; 21 | 22 | final class AsyncBlockingIterable implements Iterable { 23 | 24 | final AsyncEnumerable source; 25 | 26 | AsyncBlockingIterable(AsyncEnumerable source) { 27 | this.source = source; 28 | } 29 | 30 | @Override 31 | public Iterator iterator() { 32 | return new BlockingIterator<>(source.enumerator()); 33 | } 34 | 35 | static final class BlockingIterator implements Iterator, Runnable { 36 | 37 | final AsyncEnumerator source; 38 | 39 | boolean hasValue; 40 | 41 | boolean done; 42 | 43 | T value; 44 | 45 | BlockingIterator(AsyncEnumerator source) { 46 | this.source = source; 47 | } 48 | 49 | @Override 50 | public boolean hasNext() { 51 | if (!hasValue && !done) { 52 | try { 53 | Boolean b = source 54 | .moveNext() 55 | .toCompletableFuture() 56 | .get(); 57 | if (b) { 58 | hasValue = true; 59 | value = source.current(); 60 | } else { 61 | done = true; 62 | } 63 | } catch (InterruptedException ex) { 64 | throw new RuntimeException(ex); 65 | } catch (ExecutionException ex) { 66 | throw ThrowableHelper.wrapOrThrow(ex.getCause()); 67 | } 68 | } 69 | return hasValue; 70 | } 71 | 72 | @Override 73 | public T next() { 74 | if (hasValue || hasNext()) { 75 | T v = value; 76 | value = null; 77 | hasValue = false; 78 | return v; 79 | } 80 | throw new NoSuchElementException(); 81 | } 82 | 83 | @Override 84 | public void run() { 85 | source.cancel(); 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncBlockingLast.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.*; 20 | import java.util.concurrent.CountDownLatch; 21 | import java.util.concurrent.atomic.AtomicInteger; 22 | import java.util.function.BiConsumer; 23 | 24 | final class AsyncBlockingLast extends CountDownLatch implements BiConsumer { 25 | 26 | final AsyncEnumerator source; 27 | 28 | final AtomicInteger wip; 29 | 30 | boolean hasValue; 31 | T result; 32 | 33 | Throwable error; 34 | 35 | AsyncBlockingLast(AsyncEnumerator source) { 36 | super(1); 37 | this.source = source; 38 | this.wip = new AtomicInteger(); 39 | } 40 | 41 | void moveNext() { 42 | if (wip.getAndIncrement() == 0) { 43 | do { 44 | source.moveNext().whenComplete(this); 45 | } while (wip.decrementAndGet() != 0); 46 | } 47 | } 48 | 49 | @Override 50 | public void accept(Boolean aBoolean, Throwable throwable) { 51 | if (throwable != null) { 52 | result = null; 53 | error = throwable; 54 | countDown(); 55 | return; 56 | } 57 | 58 | if (aBoolean) { 59 | hasValue = true; 60 | result = source.current(); 61 | moveNext(); 62 | } else { 63 | countDown(); 64 | } 65 | } 66 | 67 | T blockingGet() { 68 | if (getCount() != 0) { 69 | try { 70 | await(); 71 | } catch (InterruptedException ex) { 72 | source.cancel(); 73 | throw new RuntimeException(ex); 74 | } 75 | } 76 | Throwable ex = error; 77 | if (ex != null) { 78 | throw ThrowableHelper.wrapOrThrow(ex); 79 | } 80 | if (hasValue) { 81 | return result; 82 | } 83 | throw new NoSuchElementException(); 84 | } 85 | 86 | 87 | Optional blockingGetOptional() { 88 | if (getCount() != 0) { 89 | try { 90 | await(); 91 | } catch (InterruptedException ex) { 92 | source.cancel(); 93 | throw new RuntimeException(ex); 94 | } 95 | } 96 | Throwable ex = error; 97 | if (ex != null) { 98 | throw ThrowableHelper.wrapOrThrow(ex); 99 | } 100 | if (hasValue) { 101 | return Optional.ofNullable(result); 102 | } 103 | return Optional.empty(); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncCompletableFuture.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.concurrent.CompletableFuture; 20 | import java.util.function.BiConsumer; 21 | 22 | final class AsyncCompletableFuture extends CompletableFuture 23 | implements BiConsumer { 24 | 25 | @Override 26 | public void accept(T t, Throwable throwable) { 27 | if (throwable != null) { 28 | completeExceptionally(throwable); 29 | } else { 30 | complete(t); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncDefer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.function.Supplier; 20 | 21 | final class AsyncDefer implements AsyncEnumerable { 22 | 23 | final Supplier> supplier; 24 | 25 | AsyncDefer(Supplier> supplier) { 26 | this.supplier = supplier; 27 | } 28 | 29 | @Override 30 | @SuppressWarnings("unchecked") 31 | public AsyncEnumerator enumerator() { 32 | return (AsyncEnumerator)supplier.get().enumerator(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncDoFinally.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.concurrent.*; 20 | import java.util.concurrent.atomic.AtomicBoolean; 21 | import java.util.function.BiConsumer; 22 | 23 | final class AsyncDoFinally implements AsyncEnumerable { 24 | 25 | final AsyncEnumerable source; 26 | 27 | final Runnable onFinally; 28 | 29 | AsyncDoFinally(AsyncEnumerable source, Runnable onFinally) { 30 | this.source = source; 31 | this.onFinally = onFinally; 32 | } 33 | 34 | @Override 35 | public AsyncEnumerator enumerator() { 36 | return new DoFinallyEnumerator<>(source.enumerator(), onFinally); 37 | } 38 | 39 | static final class DoFinallyEnumerator 40 | extends AtomicBoolean 41 | implements AsyncEnumerator, BiConsumer { 42 | 43 | final AsyncEnumerator source; 44 | 45 | final Runnable onFinally; 46 | 47 | CompletableFuture completable; 48 | 49 | T result; 50 | 51 | DoFinallyEnumerator(AsyncEnumerator source, Runnable onFinally) { 52 | this.source = source; 53 | this.onFinally = onFinally; 54 | } 55 | 56 | @Override 57 | public CompletionStage moveNext() { 58 | result = null; 59 | CompletableFuture cf = new CompletableFuture<>(); 60 | completable = cf; 61 | source.moveNext().whenComplete(this); 62 | return cf; 63 | } 64 | 65 | @Override 66 | public T current() { 67 | return result; 68 | } 69 | 70 | @Override 71 | public void cancel() { 72 | source.cancel(); 73 | runFinally(); 74 | } 75 | 76 | void runFinally() { 77 | if (compareAndSet(false, true)) { 78 | onFinally.run(); 79 | } 80 | } 81 | 82 | @Override 83 | public void accept(Boolean aBoolean, Throwable throwable) { 84 | if (throwable != null) { 85 | completable.completeExceptionally(throwable); 86 | runFinally(); 87 | return; 88 | } 89 | 90 | if (aBoolean) { 91 | result = source.current(); 92 | completable.complete(true); 93 | } else { 94 | completable.complete(false); 95 | runFinally(); 96 | } 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncDoOnCancel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.concurrent.CompletionStage; 20 | 21 | final class AsyncDoOnCancel implements AsyncEnumerable { 22 | 23 | final AsyncEnumerable source; 24 | 25 | final Runnable onCancel; 26 | 27 | AsyncDoOnCancel(AsyncEnumerable source, Runnable onCancel) { 28 | this.source = source; 29 | this.onCancel = onCancel; 30 | } 31 | 32 | @Override 33 | public AsyncEnumerator enumerator() { 34 | return new DoOnCancelEnumerator<>(source.enumerator(), onCancel); 35 | } 36 | 37 | static final class DoOnCancelEnumerator implements AsyncEnumerator { 38 | 39 | final AsyncEnumerator source; 40 | 41 | final Runnable onCancel; 42 | 43 | DoOnCancelEnumerator(AsyncEnumerator source, Runnable onCancel) { 44 | this.source = source; 45 | this.onCancel = onCancel; 46 | } 47 | 48 | @Override 49 | public CompletionStage moveNext() { 50 | return source.moveNext(); 51 | } 52 | 53 | @Override 54 | public T current() { 55 | return source.current(); 56 | } 57 | 58 | @Override 59 | public void cancel() { 60 | onCancel.run(); 61 | source.cancel(); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncEmitter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | public interface AsyncEmitter extends SyncEmitter { 20 | 21 | boolean isCancelled(); 22 | 23 | int emissionPending(); 24 | 25 | void setResource(AutoCloseable resource); 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncEmpty.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.concurrent.CompletionStage; 20 | 21 | enum AsyncEmpty implements AsyncEnumerable, AsyncEnumerator { 22 | INSTANCE; 23 | 24 | @SuppressWarnings("unchecked") 25 | static AsyncEnumerable instance() { 26 | return (AsyncEnumerable)INSTANCE; 27 | } 28 | 29 | @Override 30 | public AsyncEnumerator enumerator() { 31 | return this; 32 | } 33 | 34 | @Override 35 | public CompletionStage moveNext() { 36 | return FALSE; 37 | } 38 | 39 | @Override 40 | public Object current() { 41 | return null; 42 | } 43 | 44 | @Override 45 | public void cancel() { 46 | // No action, consumer should stop calling moveNext(). 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncEnumerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.concurrent.CompletionStage; 20 | 21 | public interface AsyncEnumerator { 22 | 23 | /** 24 | * Asks the AsyncEnumerator to fetch the next item and notify its availability 25 | * by completing the returned CompletionStage with: {@code true} if there is 26 | * an item is ready to be read via {@link #current()}; {@code false} if 27 | * there won't be any more items; or containing the {@code Throwable} indicating 28 | * an error. 29 | *

30 | * The method should not be called if it was called recently and the 31 | * CompletionStage hasn't terminated yet. 32 | *

33 | * @return the CompletionStage that gets terminated depending on there are more 34 | * items or an error available. 35 | */ 36 | CompletionStage moveNext(); 37 | 38 | /** 39 | * Returns the current item when the CompletionStage returned by {@link #moveNext()} 40 | * completes with {@code true}. 41 | *

42 | * This method should not be called without calling 43 | * {@code moveNext()} first and while the CompletionStage of {@code moveNext()} hasn't 44 | * completed yet or has been completed with {@code false} or with a {@code Throwable}. 45 | *

46 | * @return the item, may be null 47 | */ 48 | T current(); 49 | 50 | /** 51 | * Instructs the AsyncEnumerator to cancel any outstanding async activity and 52 | * release resources associated with it. 53 | */ 54 | void cancel(); 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncEnumeratorHelper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.concurrent.CompletionStage; 20 | import java.util.concurrent.atomic.AtomicReference; 21 | 22 | enum AsyncEnumeratorHelper implements AsyncEnumerator { 23 | 24 | CANCELLED; 25 | 26 | @Override 27 | public CompletionStage moveNext() { 28 | return AsyncEnumerable.CANCELLED; 29 | } 30 | 31 | @Override 32 | public Object current() { 33 | return null; 34 | } 35 | 36 | @Override 37 | public void cancel() { 38 | // No action, consumer should stop calling moveNext(). 39 | } 40 | 41 | @SuppressWarnings("unchecked") 42 | static boolean cancel(AtomicReference> target) { 43 | AsyncEnumerator current = target.getAndSet((AsyncEnumerator)CANCELLED); 44 | if (current != CANCELLED) { 45 | if (current != null) { 46 | current.cancel(); 47 | } 48 | return true; 49 | } 50 | return false; 51 | } 52 | 53 | static boolean replace(AtomicReference> target, AsyncEnumerator next) { 54 | for (;;) { 55 | AsyncEnumerator current = target.getAcquire(); 56 | if (current == CANCELLED) { 57 | next.cancel(); 58 | return false; 59 | } 60 | if (target.compareAndSet(current, next)) { 61 | return true; 62 | } 63 | } 64 | } 65 | 66 | static boolean isCancelled(AsyncEnumerator enumerator) { 67 | return enumerator == CANCELLED; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncError.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.concurrent.*; 20 | 21 | final class AsyncError implements AsyncEnumerable, AsyncEnumerator { 22 | 23 | final Throwable error; 24 | 25 | AsyncError(Throwable error) { 26 | this.error = error; 27 | } 28 | 29 | @Override 30 | public AsyncEnumerator enumerator() { 31 | return this; 32 | } 33 | 34 | @Override 35 | public CompletionStage moveNext() { 36 | return CompletableFuture.failedStage(error); 37 | } 38 | 39 | @Override 40 | public T current() { 41 | return null; 42 | } 43 | 44 | @Override 45 | public void cancel() { 46 | // No action, consumer should stop calling moveNext(). 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.concurrent.*; 20 | import java.util.concurrent.atomic.AtomicInteger; 21 | import java.util.function.*; 22 | 23 | final class AsyncFilter implements AsyncEnumerable { 24 | 25 | final AsyncEnumerable source; 26 | 27 | final Predicate predicate; 28 | 29 | AsyncFilter(AsyncEnumerable source, Predicate predicate) { 30 | this.source = source; 31 | this.predicate = predicate; 32 | } 33 | 34 | @Override 35 | public AsyncEnumerator enumerator() { 36 | return new FilterEnumerator<>(source.enumerator(), predicate); 37 | } 38 | 39 | static final class FilterEnumerator extends AtomicInteger implements AsyncEnumerator, BiConsumer { 40 | 41 | final AsyncEnumerator source; 42 | 43 | final Predicate predicate; 44 | 45 | CompletableFuture current; 46 | 47 | T currentItem; 48 | 49 | FilterEnumerator(AsyncEnumerator source, Predicate predicate) { 50 | this.source = source; 51 | this.predicate = predicate; 52 | } 53 | 54 | @Override 55 | public CompletionStage moveNext() { 56 | current = new CompletableFuture<>(); 57 | moveNextSource(); 58 | return current; 59 | } 60 | 61 | @Override 62 | public T current() { 63 | return currentItem; 64 | } 65 | 66 | void moveNextSource() { 67 | if (getAndIncrement() == 0) { 68 | do { 69 | source.moveNext().whenComplete(this); 70 | } while (decrementAndGet() != 0); 71 | } 72 | } 73 | 74 | @Override 75 | public void accept(Boolean aBoolean, Throwable throwable) { 76 | if (throwable != null) { 77 | currentItem = null; 78 | current.completeExceptionally(throwable); 79 | return; 80 | } 81 | 82 | if (aBoolean) { 83 | T v = source.current(); 84 | if (predicate.test(v)) { 85 | currentItem = v; 86 | current.complete(true); 87 | } else { 88 | currentItem = null; 89 | moveNextSource(); 90 | } 91 | } else { 92 | current.complete(false); 93 | } 94 | } 95 | 96 | @Override 97 | public void cancel() { 98 | source.cancel(); 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncFirst.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.concurrent.CompletionStage; 20 | 21 | final class AsyncFirst implements AsyncEnumerable { 22 | 23 | final AsyncEnumerable source; 24 | 25 | AsyncFirst(AsyncEnumerable source) { 26 | this.source = source; 27 | } 28 | 29 | @Override 30 | public AsyncEnumerator enumerator() { 31 | return new FirstEnumerator<>(source.enumerator()); 32 | } 33 | 34 | static final class FirstEnumerator implements AsyncEnumerator { 35 | 36 | final AsyncEnumerator source; 37 | 38 | boolean once; 39 | 40 | FirstEnumerator(AsyncEnumerator source) { 41 | this.source = source; 42 | } 43 | 44 | @Override 45 | public CompletionStage moveNext() { 46 | if (once) { 47 | source.cancel(); 48 | return FALSE; 49 | } 50 | once = true; 51 | return source.moveNext(); 52 | } 53 | 54 | @Override 55 | public T current() { 56 | return source.current(); 57 | } 58 | 59 | @Override 60 | public void cancel() { 61 | source.cancel(); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncForEach.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.concurrent.*; 20 | import java.util.concurrent.atomic.AtomicInteger; 21 | import java.util.function.*; 22 | 23 | final class AsyncForEach { 24 | 25 | static CompletionStage forEach( 26 | AsyncEnumerator enumerator, 27 | Consumer onValue) { 28 | CompletableFuture completion = new CompletableFuture<>(); 29 | new ForEachTrampoline<>(completion, enumerator, onValue).moveNext(); 30 | return completion; 31 | } 32 | 33 | static final class ForEachTrampoline extends AtomicInteger implements BiConsumer { 34 | final CompletableFuture completion; 35 | final AsyncEnumerator enumerator; 36 | final Consumer onValue; 37 | 38 | ForEachTrampoline(CompletableFuture completion, AsyncEnumerator enumerator, Consumer onValue) { 39 | this.completion = completion; 40 | this.enumerator = enumerator; 41 | this.onValue = onValue; 42 | } 43 | 44 | @Override 45 | public void accept(Boolean r, Throwable e) { 46 | if (e != null) { 47 | completion.completeExceptionally(e); 48 | return; 49 | } 50 | if (r) { 51 | onValue.accept(enumerator.current()); 52 | moveNext(); 53 | } else { 54 | completion.complete(true); 55 | } 56 | } 57 | 58 | void moveNext() { 59 | if (getAndIncrement() != 0) { 60 | return; 61 | } 62 | 63 | do { 64 | CompletionStage next = enumerator.moveNext(); 65 | next.whenComplete(this); 66 | } while (decrementAndGet() != 0); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncFromArray.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.concurrent.CompletionStage; 20 | 21 | final class AsyncFromArray implements AsyncEnumerable { 22 | 23 | final T[] array; 24 | 25 | AsyncFromArray(T[] array) { 26 | this.array = array; 27 | } 28 | 29 | @Override 30 | public AsyncEnumerator enumerator() { 31 | return new FromArrayEnumerator<>(array); 32 | } 33 | 34 | static final class FromArrayEnumerator implements AsyncEnumerator { 35 | 36 | final T[] array; 37 | 38 | int index; 39 | 40 | T current; 41 | 42 | FromArrayEnumerator(T[] array) { 43 | this.array = array; 44 | } 45 | 46 | @Override 47 | public CompletionStage moveNext() { 48 | int idx = index; 49 | if (idx == array.length) { 50 | current = null; 51 | return FALSE; 52 | } 53 | current = array[idx]; 54 | index = idx + 1; 55 | return TRUE; 56 | } 57 | 58 | @Override 59 | public T current() { 60 | return current; 61 | } 62 | 63 | @Override 64 | public void cancel() { 65 | // No action, consumer should stop calling moveNext(). 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncFromCallable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.concurrent.*; 20 | 21 | final class AsyncFromCallable implements AsyncEnumerable { 22 | 23 | final Callable callable; 24 | 25 | AsyncFromCallable(Callable callable) { 26 | this.callable = callable; 27 | } 28 | 29 | @Override 30 | public AsyncEnumerator enumerator() { 31 | return new FromCallableEnumerator<>(callable); 32 | } 33 | 34 | static final class FromCallableEnumerator implements AsyncEnumerator { 35 | 36 | final Callable callable; 37 | 38 | T result; 39 | 40 | boolean once; 41 | 42 | FromCallableEnumerator(Callable callable) { 43 | this.callable = callable; 44 | } 45 | 46 | @Override 47 | public CompletionStage moveNext() { 48 | if (once) { 49 | result = null; 50 | return FALSE; 51 | } 52 | once = true; 53 | try { 54 | result = callable.call(); 55 | } catch (Exception ex) { 56 | return CompletableFuture.failedStage(ex); 57 | } 58 | return TRUE; 59 | } 60 | 61 | @Override 62 | public T current() { 63 | return result; 64 | } 65 | 66 | @Override 67 | public void cancel() { 68 | // No action, consumer should stop calling moveNext(). 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncFromCharSequence.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.concurrent.CompletionStage; 20 | 21 | final class AsyncFromCharSequence implements AsyncEnumerable { 22 | 23 | final CharSequence array; 24 | 25 | AsyncFromCharSequence(CharSequence array) { 26 | this.array = array; 27 | } 28 | 29 | @Override 30 | public AsyncEnumerator enumerator() { 31 | return new FromCharSequenceEnumerator(array); 32 | } 33 | 34 | static final class FromCharSequenceEnumerator implements AsyncEnumerator { 35 | 36 | final CharSequence array; 37 | 38 | int index; 39 | 40 | Integer current; 41 | 42 | FromCharSequenceEnumerator(CharSequence array) { 43 | this.array = array; 44 | } 45 | 46 | @Override 47 | public CompletionStage moveNext() { 48 | int idx = index; 49 | if (idx == array.length()) { 50 | current = null; 51 | return FALSE; 52 | } 53 | current = (int)array.charAt(idx); 54 | index = idx + 1; 55 | return TRUE; 56 | } 57 | 58 | @Override 59 | public Integer current() { 60 | return current; 61 | } 62 | 63 | @Override 64 | public void cancel() { 65 | // No action, consumer should stop calling moveNext(). 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncFromCompletionStage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.concurrent.*; 20 | import java.util.function.*; 21 | 22 | final class AsyncFromCompletionStage implements AsyncEnumerable { 23 | 24 | final CompletionStage source; 25 | 26 | AsyncFromCompletionStage(CompletionStage source) { 27 | this.source = source; 28 | } 29 | 30 | @Override 31 | public AsyncEnumerator enumerator() { 32 | return new FromCompletionStageAsyncEnumerable<>(source); 33 | } 34 | 35 | static final class FromCompletionStageAsyncEnumerable 36 | implements AsyncEnumerator, BiConsumer { 37 | 38 | final CompletionStage stage; 39 | 40 | CompletableFuture completable; 41 | 42 | boolean once; 43 | 44 | T result; 45 | 46 | FromCompletionStageAsyncEnumerable(CompletionStage stage) { 47 | this.stage = stage; 48 | } 49 | 50 | @Override 51 | public CompletionStage moveNext() { 52 | if (once) { 53 | result = null; 54 | return FALSE; 55 | } 56 | once = true; 57 | CompletableFuture cf = new CompletableFuture<>(); 58 | completable = cf; 59 | stage.whenComplete(this); 60 | return cf; 61 | } 62 | 63 | @Override 64 | public T current() { 65 | return result; 66 | } 67 | 68 | @Override 69 | public void accept(T t, Throwable throwable) { 70 | if (throwable != null) { 71 | completable.completeExceptionally(throwable); 72 | } else { 73 | result = t; 74 | completable.complete(true); 75 | } 76 | } 77 | 78 | @Override 79 | public void cancel() { 80 | // No action, consumer should stop calling moveNext(). 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncFromIterable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.Iterator; 20 | import java.util.concurrent.CompletionStage; 21 | 22 | final class AsyncFromIterable implements AsyncEnumerable { 23 | 24 | final Iterable iterable; 25 | 26 | AsyncFromIterable(Iterable iterable) { 27 | this.iterable = iterable; 28 | } 29 | 30 | @Override 31 | public AsyncEnumerator enumerator() { 32 | return new FromIteratorEnumerator<>(iterable.iterator()); 33 | } 34 | 35 | static final class FromIteratorEnumerator implements AsyncEnumerator { 36 | 37 | final Iterator iterator; 38 | 39 | T current; 40 | 41 | FromIteratorEnumerator(Iterator iterable) { 42 | this.iterator = iterable; 43 | } 44 | 45 | @Override 46 | public CompletionStage moveNext() { 47 | if (iterator.hasNext()) { 48 | current = iterator.next(); 49 | return TRUE; 50 | } 51 | current = null; 52 | return FALSE; 53 | } 54 | 55 | @Override 56 | public T current() { 57 | return current; 58 | } 59 | 60 | @Override 61 | public void cancel() { 62 | // No action, consumer should stop calling moveNext(). 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncFromStream.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.Iterator; 20 | import java.util.concurrent.CompletionStage; 21 | import java.util.concurrent.atomic.AtomicBoolean; 22 | import java.util.stream.Stream; 23 | 24 | final class AsyncFromStream implements AsyncEnumerable { 25 | 26 | final Stream stream; 27 | 28 | AsyncFromStream(Stream stream) { 29 | this.stream = stream; 30 | } 31 | 32 | @Override 33 | public AsyncEnumerator enumerator() { 34 | try { 35 | return new StreamEnumerator<>(stream.iterator(), stream); 36 | } catch (RuntimeException ex) { 37 | return new AsyncError<>(ex); 38 | } 39 | } 40 | 41 | static final class StreamEnumerator 42 | extends AtomicBoolean 43 | implements AsyncEnumerator { 44 | 45 | final Iterator source; 46 | 47 | final Stream closeable; 48 | 49 | T current; 50 | 51 | StreamEnumerator(Iterator source, Stream closeable) { 52 | this.source = source; 53 | this.closeable = closeable; 54 | } 55 | 56 | @Override 57 | public CompletionStage moveNext() { 58 | if (source.hasNext()) { 59 | current = source.next(); 60 | return TRUE; 61 | } 62 | current = null; 63 | cancel(); 64 | return FALSE; 65 | } 66 | 67 | @Override 68 | public T current() { 69 | return current; 70 | } 71 | 72 | @Override 73 | public void cancel() { 74 | if (compareAndSet(false, true)) { 75 | closeable.close(); 76 | } 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncIgnoreElements.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.concurrent.*; 20 | import java.util.concurrent.atomic.AtomicInteger; 21 | import java.util.function.BiConsumer; 22 | 23 | final class AsyncIgnoreElements implements AsyncEnumerable { 24 | 25 | final AsyncEnumerable source; 26 | 27 | AsyncIgnoreElements(AsyncEnumerable source) { 28 | this.source = source; 29 | } 30 | 31 | @Override 32 | public AsyncEnumerator enumerator() { 33 | return new IgnoreElementsEnumerator<>(source.enumerator()); 34 | } 35 | 36 | static final class IgnoreElementsEnumerator 37 | extends AtomicInteger 38 | implements AsyncEnumerator, BiConsumer { 39 | 40 | final AsyncEnumerator source; 41 | 42 | CompletableFuture completable; 43 | 44 | volatile boolean cancelled; 45 | 46 | IgnoreElementsEnumerator(AsyncEnumerator source) { 47 | this.source = source; 48 | } 49 | 50 | @Override 51 | public CompletionStage moveNext() { 52 | CompletableFuture cf = new CompletableFuture<>(); 53 | completable = cf; 54 | nextSource(); 55 | return cf; 56 | } 57 | 58 | void nextSource() { 59 | if (getAndIncrement() == 0) { 60 | do { 61 | if (cancelled) { 62 | return; 63 | } 64 | source.moveNext().whenComplete(this); 65 | } while (decrementAndGet() != 0); 66 | } 67 | } 68 | 69 | @Override 70 | public T current() { 71 | return null; // elements are ignored 72 | } 73 | 74 | @Override 75 | public void cancel() { 76 | cancelled = true; 77 | source.cancel(); 78 | } 79 | 80 | @Override 81 | public void accept(Boolean aBoolean, Throwable throwable) { 82 | if (throwable != null) { 83 | completable.completeExceptionally(throwable); 84 | return; 85 | } 86 | if (aBoolean) { 87 | nextSource(); 88 | } else { 89 | completable.complete(false); 90 | } 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncInterval.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.concurrent.*; 20 | import java.util.concurrent.atomic.*; 21 | import java.util.function.BiConsumer; 22 | 23 | final class AsyncInterval implements AsyncEnumerable { 24 | 25 | final long initialDelay; 26 | 27 | final long period; 28 | 29 | final TimeUnit unit; 30 | 31 | final ScheduledExecutorService executor; 32 | 33 | AsyncInterval(long initialDelay, long period, TimeUnit unit, ScheduledExecutorService executor) { 34 | this.initialDelay = initialDelay; 35 | this.period = period; 36 | this.unit = unit; 37 | this.executor = executor; 38 | } 39 | 40 | @Override 41 | public AsyncEnumerator enumerator() { 42 | IntervalEnumerator enumerator = new IntervalEnumerator(); 43 | enumerator.task = executor.scheduleAtFixedRate(enumerator, initialDelay, period, unit); 44 | return enumerator; 45 | } 46 | 47 | static final class IntervalEnumerator 48 | extends AtomicInteger 49 | implements AsyncEnumerator, Runnable { 50 | 51 | final AtomicLong available; 52 | 53 | Future task; 54 | 55 | long emitted; 56 | 57 | volatile CompletableFuture completable; 58 | 59 | Long result; 60 | 61 | IntervalEnumerator() { 62 | available = new AtomicLong(); 63 | } 64 | 65 | @Override 66 | public CompletionStage moveNext() { 67 | result = null; 68 | CompletableFuture cf = new CompletableFuture<>(); 69 | completable = cf; 70 | drain(); 71 | return cf; 72 | } 73 | 74 | @Override 75 | public Long current() { 76 | return result; 77 | } 78 | 79 | @Override 80 | public void run() { 81 | available.getAndIncrement(); 82 | drain(); 83 | } 84 | 85 | void drain() { 86 | if (getAndIncrement() == 0) { 87 | do { 88 | if (emitted != available.get()) { 89 | result = emitted++; 90 | completable.complete(true); 91 | } 92 | } while (decrementAndGet() != 0); 93 | } 94 | } 95 | 96 | @Override 97 | public void cancel() { 98 | task.cancel(false); 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncJust.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.concurrent.CompletionStage; 20 | 21 | final class AsyncJust implements AsyncEnumerable { 22 | 23 | final T value; 24 | 25 | AsyncJust(T value) { 26 | this.value = value; 27 | } 28 | 29 | @Override 30 | public AsyncEnumerator enumerator() { 31 | return new JustEnumerator<>(value); 32 | } 33 | 34 | static final class JustEnumerator implements AsyncEnumerator { 35 | 36 | final T value; 37 | 38 | boolean once; 39 | 40 | JustEnumerator(T value) { 41 | this.value = value; 42 | } 43 | 44 | @Override 45 | public CompletionStage moveNext() { 46 | if (once) { 47 | return FALSE; 48 | } 49 | once = true; 50 | return TRUE; 51 | } 52 | 53 | @Override 54 | public T current() { 55 | return value; 56 | } 57 | 58 | @Override 59 | public void cancel() { 60 | // No action, consumer should stop calling moveNext(). 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncLast.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.concurrent.*; 20 | import java.util.concurrent.atomic.AtomicInteger; 21 | import java.util.function.BiConsumer; 22 | 23 | final class AsyncLast implements AsyncEnumerable { 24 | 25 | final AsyncEnumerable source; 26 | 27 | AsyncLast(AsyncEnumerable source) { 28 | this.source = source; 29 | } 30 | 31 | @Override 32 | public AsyncEnumerator enumerator() { 33 | return new LastEnumerator<>(source.enumerator()); 34 | } 35 | 36 | static final class LastEnumerator 37 | extends AtomicInteger 38 | implements AsyncEnumerator, BiConsumer { 39 | 40 | final AsyncEnumerator source; 41 | 42 | volatile boolean cancelled; 43 | 44 | CompletableFuture completable; 45 | 46 | T result; 47 | 48 | boolean once; 49 | 50 | boolean hasValue; 51 | 52 | LastEnumerator(AsyncEnumerator source) { 53 | this.source = source; 54 | } 55 | 56 | @Override 57 | public CompletionStage moveNext() { 58 | if (once) { 59 | result = null; 60 | return FALSE; 61 | } 62 | once = true; 63 | CompletableFuture cf = new CompletableFuture<>(); 64 | completable = cf; 65 | nextSource(); 66 | return cf; 67 | } 68 | 69 | void nextSource() { 70 | if (getAndIncrement() == 0) { 71 | do { 72 | source.moveNext().whenComplete(this); 73 | } while (decrementAndGet() != 0); 74 | } 75 | } 76 | 77 | @Override 78 | public T current() { 79 | return result; 80 | } 81 | 82 | @Override 83 | public void cancel() { 84 | cancelled = true; 85 | source.cancel(); 86 | } 87 | 88 | @Override 89 | public void accept(Boolean aBoolean, Throwable throwable) { 90 | if (throwable != null) { 91 | completable.completeExceptionally(throwable); 92 | return; 93 | } 94 | 95 | if (aBoolean) { 96 | if (!hasValue) { 97 | hasValue = true; 98 | } 99 | result = source.current(); 100 | nextSource(); 101 | } else { 102 | completable.complete(hasValue); 103 | } 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncMap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.concurrent.CompletionStage; 20 | import java.util.function.*; 21 | 22 | final class AsyncMap implements AsyncEnumerable { 23 | 24 | final AsyncEnumerable source; 25 | 26 | final Function mapper; 27 | 28 | AsyncMap(AsyncEnumerable source, Function mapper) { 29 | this.source = source; 30 | this.mapper = mapper; 31 | } 32 | 33 | @Override 34 | public AsyncEnumerator enumerator() { 35 | return new MapEnumerator<>(source.enumerator(), mapper); 36 | } 37 | 38 | static final class MapEnumerator implements AsyncEnumerator { 39 | 40 | final AsyncEnumerator source; 41 | 42 | final Function mapper; 43 | 44 | MapEnumerator(AsyncEnumerator source, Function mapper) { 45 | this.source = source; 46 | this.mapper = mapper; 47 | } 48 | 49 | @Override 50 | public CompletionStage moveNext() { 51 | return source.moveNext(); 52 | } 53 | 54 | @Override 55 | public R current() { 56 | return mapper.apply(source.current()); 57 | } 58 | 59 | @Override 60 | public void cancel() { 61 | source.cancel(); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncNever.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.concurrent.*; 20 | 21 | enum AsyncNever implements AsyncEnumerable, AsyncEnumerator { 22 | 23 | INSTANCE; 24 | 25 | @SuppressWarnings("unchecked") 26 | public static AsyncEnumerable instance() { 27 | return (AsyncEnumerable)INSTANCE; 28 | } 29 | 30 | @Override 31 | public AsyncEnumerator enumerator() { 32 | return this; 33 | } 34 | 35 | @Override 36 | public CompletionStage moveNext() { 37 | return new CompletableFuture<>(); 38 | } 39 | 40 | @Override 41 | public Object current() { 42 | return null; 43 | } 44 | 45 | @Override 46 | public void cancel() { 47 | // No action, consumer should stop calling moveNext(). 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncObserveOn.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.concurrent.*; 20 | 21 | final class AsyncObserveOn implements AsyncEnumerable { 22 | 23 | final AsyncEnumerable source; 24 | 25 | final Executor executor; 26 | 27 | AsyncObserveOn(AsyncEnumerable source, Executor executor) { 28 | this.source = source; 29 | this.executor = executor; 30 | } 31 | 32 | @Override 33 | public AsyncEnumerator enumerator() { 34 | return new ObserveOnEnumerator<>(source.enumerator(), executor); 35 | } 36 | 37 | static final class ObserveOnEnumerator implements AsyncEnumerator { 38 | 39 | final AsyncEnumerator source; 40 | 41 | final Executor executor; 42 | 43 | ObserveOnEnumerator(AsyncEnumerator source, Executor executor) { 44 | this.source = source; 45 | this.executor = executor; 46 | } 47 | 48 | @Override 49 | public CompletionStage moveNext() { 50 | AsyncCompletableFuture cf = new AsyncCompletableFuture<>(); 51 | source.moveNext().whenCompleteAsync(cf, executor); 52 | return cf; 53 | } 54 | 55 | @Override 56 | public T current() { 57 | return source.current(); 58 | } 59 | 60 | @Override 61 | public void cancel() { 62 | source.cancel(); 63 | } 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncRange.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.concurrent.CompletionStage; 20 | import java.util.function.Consumer; 21 | 22 | final class AsyncRange implements AsyncEnumerable { 23 | 24 | final int start; 25 | 26 | final int count; 27 | 28 | AsyncRange(int start, int count) { 29 | this.start = start; 30 | this.count = count; 31 | } 32 | 33 | @Override 34 | public AsyncEnumerator enumerator() { 35 | return new AsyncRangeEnumerator(start, start + count); 36 | } 37 | 38 | static final class AsyncRangeEnumerator implements AsyncEnumerator { 39 | 40 | final int end; 41 | 42 | int index; 43 | 44 | Integer current; 45 | 46 | AsyncRangeEnumerator(int start, int end) { 47 | this.index = start; 48 | this.end = end; 49 | } 50 | 51 | @Override 52 | public CompletionStage moveNext() { 53 | int idx = index; 54 | if (idx == end) { 55 | current = null; 56 | return FALSE; 57 | } 58 | current = idx; 59 | index = idx + 1; 60 | return TRUE; 61 | } 62 | 63 | @Override 64 | public Integer current() { 65 | return current; 66 | } 67 | 68 | @Override 69 | public void cancel() { 70 | // No action, consumer should stop calling moveNext(). 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncRepeatCallable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.concurrent.*; 20 | 21 | final class AsyncRepeatCallable implements AsyncEnumerable { 22 | 23 | final Callable callable; 24 | 25 | AsyncRepeatCallable(Callable callable) { 26 | this.callable = callable; 27 | } 28 | 29 | @Override 30 | public AsyncEnumerator enumerator() { 31 | return new RepeatCallableEnumerator<>(callable); 32 | } 33 | 34 | static final class RepeatCallableEnumerator implements AsyncEnumerator { 35 | 36 | final Callable callable; 37 | 38 | T result; 39 | 40 | RepeatCallableEnumerator(Callable callable) { 41 | this.callable = callable; 42 | } 43 | 44 | @Override 45 | public CompletionStage moveNext() { 46 | result = null; 47 | try { 48 | result = callable.call(); 49 | } catch (Exception ex) { 50 | return CompletableFuture.failedStage(ex); 51 | } 52 | return TRUE; 53 | } 54 | 55 | @Override 56 | public T current() { 57 | return result; 58 | } 59 | 60 | @Override 61 | public void cancel() { 62 | // No action, consumer should stop calling moveNext(). 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncRepeatItem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.concurrent.CompletionStage; 20 | 21 | final class AsyncRepeatItem implements AsyncEnumerable, AsyncEnumerator { 22 | 23 | final T item; 24 | 25 | AsyncRepeatItem(T item) { 26 | this.item = item; 27 | } 28 | 29 | @Override 30 | public AsyncEnumerator enumerator() { 31 | return this; 32 | } 33 | 34 | @Override 35 | public CompletionStage moveNext() { 36 | return TRUE; 37 | } 38 | 39 | @Override 40 | public T current() { 41 | return item; 42 | } 43 | 44 | @Override 45 | public void cancel() { 46 | // No action, consumer should stop calling moveNext(). 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncSkip.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.concurrent.*; 20 | import java.util.concurrent.atomic.AtomicInteger; 21 | import java.util.function.BiConsumer; 22 | 23 | final class AsyncSkip implements AsyncEnumerable { 24 | 25 | final AsyncEnumerable upstream; 26 | 27 | final long n; 28 | 29 | AsyncSkip(AsyncEnumerable upstream, long n) { 30 | this.upstream = upstream; 31 | this.n = n; 32 | } 33 | 34 | @Override 35 | public AsyncEnumerator enumerator() { 36 | return new SkipEnumerator<>(upstream.enumerator(), n); 37 | } 38 | 39 | static final class SkipEnumerator extends AtomicInteger 40 | implements AsyncEnumerator, BiConsumer { 41 | 42 | final AsyncEnumerator source; 43 | 44 | long n; 45 | 46 | CompletableFuture cf; 47 | 48 | SkipEnumerator(AsyncEnumerator source, long n) { 49 | this.source = source; 50 | this.n = n + 1; 51 | this.cf = new CompletableFuture<>(); 52 | } 53 | 54 | @Override 55 | public CompletionStage moveNext() { 56 | if (n > 0L) { 57 | CompletableFuture nx = cf; 58 | if (getAndIncrement() == 0) { 59 | do { 60 | source.moveNext().whenComplete(this); 61 | } while (decrementAndGet() != 0); 62 | } 63 | return nx; 64 | } 65 | return source.moveNext(); 66 | } 67 | 68 | @Override 69 | public T current() { 70 | return source.current(); 71 | } 72 | 73 | @Override 74 | public void accept(Boolean aBoolean, Throwable throwable) { 75 | CompletableFuture nx = cf; 76 | if (throwable != null) { 77 | cf = null; 78 | nx.completeExceptionally(throwable); 79 | return; 80 | } 81 | if (aBoolean) { 82 | if (--n <= 0L) { 83 | cf = null; 84 | nx.complete(true); 85 | } else { 86 | moveNext(); 87 | } 88 | } else { 89 | cf = null; 90 | nx.complete(false); 91 | } 92 | } 93 | 94 | @Override 95 | public void cancel() { 96 | source.cancel(); 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncSkipWhile.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.concurrent.*; 20 | import java.util.concurrent.atomic.AtomicInteger; 21 | import java.util.function.*; 22 | 23 | final class AsyncSkipWhile implements AsyncEnumerable { 24 | 25 | final AsyncEnumerable source; 26 | 27 | final Predicate predicate; 28 | 29 | AsyncSkipWhile(AsyncEnumerable source, Predicate predicate) { 30 | this.source = source; 31 | this.predicate = predicate; 32 | } 33 | 34 | @Override 35 | public AsyncEnumerator enumerator() { 36 | return new SkipWhileEnumerator<>(source.enumerator(), predicate); 37 | } 38 | 39 | static final class SkipWhileEnumerator 40 | extends AtomicInteger 41 | implements AsyncEnumerator, BiConsumer { 42 | 43 | final AsyncEnumerator source; 44 | 45 | final Predicate predicate; 46 | 47 | boolean passThrough; 48 | 49 | CompletableFuture completable; 50 | 51 | T current; 52 | 53 | SkipWhileEnumerator(AsyncEnumerator source, Predicate predicate) { 54 | this.source = source; 55 | this.predicate = predicate; 56 | } 57 | 58 | @Override 59 | public CompletionStage moveNext() { 60 | current = null; 61 | CompletableFuture cf = new CompletableFuture<>(); 62 | completable = cf; 63 | nextSource(); 64 | return cf; 65 | } 66 | 67 | void nextSource() { 68 | if (getAndIncrement() == 0) { 69 | do { 70 | source.moveNext().whenComplete(this); 71 | } while (decrementAndGet() != 0); 72 | } 73 | } 74 | 75 | @Override 76 | public T current() { 77 | return current; 78 | } 79 | 80 | @Override 81 | public void cancel() { 82 | source.cancel(); 83 | } 84 | 85 | @Override 86 | public void accept(Boolean aBoolean, Throwable throwable) { 87 | if (throwable != null) { 88 | completable.completeExceptionally(throwable); 89 | return; 90 | } 91 | 92 | if (aBoolean) { 93 | T v = source.current(); 94 | if (!passThrough) { 95 | if (predicate.test(v)) { 96 | nextSource(); 97 | return; 98 | } else { 99 | passThrough = true; 100 | } 101 | } 102 | current = v; 103 | completable.complete(true); 104 | } else { 105 | completable.complete(false); 106 | } 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncSubscribeOn.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.concurrent.*; 20 | 21 | final class AsyncSubscribeOn implements AsyncEnumerable { 22 | 23 | final AsyncEnumerable source; 24 | 25 | final Executor executor; 26 | 27 | AsyncSubscribeOn(AsyncEnumerable source, Executor executor) { 28 | this.source = source; 29 | this.executor = executor; 30 | } 31 | 32 | 33 | @Override 34 | public AsyncEnumerator enumerator() { 35 | SubscribeOnEnumerator en = new SubscribeOnEnumerator<>(source); 36 | executor.execute(en); 37 | return en; 38 | } 39 | 40 | static final class SubscribeOnEnumerator implements AsyncEnumerator, Runnable { 41 | 42 | final CompletableFuture> source; 43 | 44 | final AsyncEnumerable upstream; 45 | 46 | SubscribeOnEnumerator(AsyncEnumerable upstream) { 47 | this.upstream = upstream; 48 | this.source = new CompletableFuture<>(); 49 | } 50 | 51 | @Override 52 | public CompletionStage moveNext() { 53 | AsyncEnumerator en = source.getNow(null); 54 | if (en != null) { 55 | return en.moveNext(); 56 | } 57 | return source.thenCompose(AsyncEnumerator::moveNext); 58 | } 59 | 60 | @Override 61 | public T current() { 62 | AsyncEnumerator en = source.getNow(null); 63 | return en != null ? en.current() : null; 64 | } 65 | 66 | @Override 67 | public void run() { 68 | AsyncEnumerator en = upstream.enumerator(); 69 | if (!source.complete(en)) { 70 | en.cancel(); 71 | } 72 | } 73 | 74 | @Override 75 | public void cancel() { 76 | if (!source.completeExceptionally(new CancellationException())) { 77 | AsyncEnumerator en = source.getNow(null); 78 | if (en != null) { 79 | en.cancel(); 80 | } 81 | } 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncSwitchIfEmpty.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.concurrent.*; 20 | import java.util.concurrent.atomic.AtomicReference; 21 | import java.util.function.BiConsumer; 22 | 23 | final class AsyncSwitchIfEmpty implements AsyncEnumerable { 24 | 25 | final AsyncEnumerable source; 26 | 27 | final AsyncEnumerable fallback; 28 | 29 | AsyncSwitchIfEmpty(AsyncEnumerable source, AsyncEnumerable fallback) { 30 | this.source = source; 31 | this.fallback = fallback; 32 | } 33 | 34 | @Override 35 | public AsyncEnumerator enumerator() { 36 | return new SwitchIfEmptyEnumerator<>(source.enumerator(), fallback); 37 | } 38 | 39 | static final class SwitchIfEmptyEnumerator 40 | implements AsyncEnumerator, BiConsumer { 41 | 42 | final AtomicReference> source; 43 | 44 | AsyncEnumerable fallback; 45 | 46 | CompletableFuture completable; 47 | 48 | T result; 49 | 50 | boolean hasValue; 51 | 52 | SwitchIfEmptyEnumerator(AsyncEnumerator source, AsyncEnumerable fallback) { 53 | this.source = new AtomicReference<>(source); 54 | this.fallback = fallback; 55 | } 56 | 57 | @Override 58 | public CompletionStage moveNext() { 59 | result = null; 60 | CompletableFuture cf = new CompletableFuture<>(); 61 | completable = cf; 62 | source.getPlain().moveNext().whenComplete(this); 63 | return cf; 64 | } 65 | 66 | @Override 67 | public T current() { 68 | return result; 69 | } 70 | 71 | @Override 72 | public void cancel() { 73 | AsyncEnumeratorHelper.cancel(source); 74 | } 75 | 76 | @Override 77 | public void accept(Boolean aBoolean, Throwable throwable) { 78 | if (throwable != null) { 79 | completable.completeExceptionally(throwable); 80 | return; 81 | } 82 | 83 | if (aBoolean) { 84 | if (!hasValue) { 85 | hasValue = true; 86 | } 87 | result = source.getPlain().current(); 88 | completable.complete(true); 89 | } else { 90 | if (hasValue) { 91 | completable.complete(false); 92 | } else { 93 | hasValue = true; 94 | AsyncEnumerator fb = fallback.enumerator(); 95 | fallback = null; 96 | if (AsyncEnumeratorHelper.replace(source, fb)) { 97 | fb.moveNext().whenComplete(this); 98 | } 99 | } 100 | } 101 | } 102 | } 103 | } 104 | 105 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncTake.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.concurrent.CompletionStage; 20 | 21 | final class AsyncTake implements AsyncEnumerable { 22 | 23 | final AsyncEnumerable upstream; 24 | 25 | final long n; 26 | 27 | AsyncTake(AsyncEnumerable upstream, long n) { 28 | this.upstream = upstream; 29 | this.n = n; 30 | } 31 | 32 | @Override 33 | public AsyncEnumerator enumerator() { 34 | return new TakeEnumerator<>(upstream.enumerator(), n); 35 | } 36 | 37 | static final class TakeEnumerator implements AsyncEnumerator { 38 | 39 | final AsyncEnumerator source; 40 | 41 | long n; 42 | 43 | TakeEnumerator(AsyncEnumerator source, long n) { 44 | this.source = source; 45 | this.n = n; 46 | } 47 | 48 | @Override 49 | public CompletionStage moveNext() { 50 | if (n-- <= 0L) { 51 | source.cancel(); 52 | return FALSE; 53 | } 54 | return source.moveNext(); 55 | } 56 | 57 | @Override 58 | public T current() { 59 | return source.current(); 60 | } 61 | 62 | @Override 63 | public void cancel() { 64 | source.cancel(); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncTakeUntilPredicate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.concurrent.*; 20 | import java.util.function.*; 21 | 22 | final class AsyncTakeUntilPredicate implements AsyncEnumerable { 23 | 24 | final AsyncEnumerable source; 25 | 26 | final Predicate stopPredicate; 27 | 28 | AsyncTakeUntilPredicate(AsyncEnumerable source, Predicate stopPredicate) { 29 | this.source = source; 30 | this.stopPredicate = stopPredicate; 31 | } 32 | 33 | @Override 34 | public AsyncEnumerator enumerator() { 35 | return new TakeUntilPredicateEnumerator<>(source.enumerator(), stopPredicate); 36 | } 37 | 38 | static final class TakeUntilPredicateEnumerator implements AsyncEnumerator, BiConsumer { 39 | 40 | final AsyncEnumerator source; 41 | 42 | final Predicate stopPredicate; 43 | 44 | CompletableFuture completable; 45 | 46 | T current; 47 | 48 | boolean stop; 49 | 50 | TakeUntilPredicateEnumerator(AsyncEnumerator source, Predicate stopPredicate) { 51 | this.source = source; 52 | this.stopPredicate = stopPredicate; 53 | } 54 | 55 | @Override 56 | public CompletionStage moveNext() { 57 | current = null; 58 | if (stop) { 59 | source.cancel(); 60 | return FALSE; 61 | } 62 | CompletableFuture cf = new CompletableFuture<>(); 63 | completable = cf; 64 | source.moveNext().whenComplete(this); 65 | return cf; 66 | } 67 | 68 | @Override 69 | public T current() { 70 | return current; 71 | } 72 | 73 | @Override 74 | public void cancel() { 75 | source.cancel(); 76 | } 77 | 78 | @Override 79 | public void accept(Boolean aBoolean, Throwable throwable) { 80 | if (throwable != null) { 81 | completable.completeExceptionally(throwable); 82 | return; 83 | } 84 | 85 | if (aBoolean) { 86 | T v = source.current(); 87 | current = v; 88 | if (stopPredicate.test(v)) { 89 | stop = true; 90 | } 91 | completable.complete(true); 92 | } else { 93 | completable.complete(false); 94 | } 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncTakeWhile.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.concurrent.*; 20 | import java.util.function.*; 21 | 22 | final class AsyncTakeWhile implements AsyncEnumerable { 23 | 24 | final AsyncEnumerable source; 25 | 26 | final Predicate predicate; 27 | 28 | AsyncTakeWhile(AsyncEnumerable source, Predicate predicate) { 29 | this.source = source; 30 | this.predicate = predicate; 31 | } 32 | 33 | @Override 34 | public AsyncEnumerator enumerator() { 35 | return new TakeWhileEnumerator<>(source.enumerator(), predicate); 36 | } 37 | 38 | static final class TakeWhileEnumerator implements AsyncEnumerator, BiConsumer { 39 | 40 | final AsyncEnumerator source; 41 | 42 | final Predicate predicate; 43 | 44 | CompletableFuture completable; 45 | 46 | T current; 47 | 48 | TakeWhileEnumerator(AsyncEnumerator source, Predicate predicate) { 49 | this.source = source; 50 | this.predicate = predicate; 51 | } 52 | 53 | @Override 54 | public CompletionStage moveNext() { 55 | current = null; 56 | CompletableFuture cf = new CompletableFuture<>(); 57 | completable = cf; 58 | source.moveNext().whenComplete(this); 59 | return cf; 60 | } 61 | 62 | @Override 63 | public T current() { 64 | return current; 65 | } 66 | 67 | @Override 68 | public void cancel() { 69 | source.cancel(); 70 | } 71 | 72 | @Override 73 | public void accept(Boolean aBoolean, Throwable throwable) { 74 | if (throwable != null) { 75 | completable.completeExceptionally(throwable); 76 | return; 77 | } 78 | 79 | if (aBoolean) { 80 | T v = source.current(); 81 | if (predicate.test(v)) { 82 | current = v; 83 | completable.complete(true); 84 | } else { 85 | source.cancel(); 86 | completable.complete(false); 87 | } 88 | } else { 89 | completable.complete(false); 90 | } 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncTimer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.concurrent.*; 20 | 21 | final class AsyncTimer implements AsyncEnumerable { 22 | 23 | final long time; 24 | 25 | final TimeUnit unit; 26 | 27 | final ScheduledExecutorService executor; 28 | 29 | AsyncTimer(long time, TimeUnit unit, ScheduledExecutorService executor) { 30 | this.time = time; 31 | this.unit = unit; 32 | this.executor = executor; 33 | } 34 | 35 | @Override 36 | public AsyncEnumerator enumerator() { 37 | TimerEnumerator en = new TimerEnumerator(); 38 | en.task = executor.schedule(en, time, unit); 39 | return en; 40 | } 41 | 42 | static final class TimerEnumerator implements AsyncEnumerator, Callable { 43 | 44 | final CompletableFuture single = new CompletableFuture<>(); 45 | 46 | Long result; 47 | 48 | boolean once; 49 | 50 | Future task; 51 | 52 | @Override 53 | public CompletionStage moveNext() { 54 | if (once) { 55 | result = null; 56 | return FALSE; 57 | } 58 | once = true; 59 | return single; 60 | } 61 | 62 | @Override 63 | public Long current() { 64 | return result; 65 | } 66 | 67 | @Override 68 | public Void call() throws Exception { 69 | result = 0L; 70 | single.complete(true); 71 | return null; 72 | } 73 | 74 | @Override 75 | public void cancel() { 76 | task.cancel(false); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/AsyncUsing.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.concurrent.*; 20 | import java.util.concurrent.atomic.AtomicBoolean; 21 | import java.util.function.*; 22 | 23 | final class AsyncUsing implements AsyncEnumerable { 24 | 25 | final Supplier resource; 26 | 27 | final Function> handler; 28 | 29 | final Consumer releaseResource; 30 | 31 | AsyncUsing(Supplier resource, Function> handler, Consumer releaseResource) { 32 | this.resource = resource; 33 | this.handler = handler; 34 | this.releaseResource = releaseResource; 35 | } 36 | 37 | @Override 38 | public AsyncEnumerator enumerator() { 39 | U res = resource.get(); 40 | return new UsingEnumerator<>(res, handler.apply(res).enumerator(), releaseResource); 41 | } 42 | 43 | static final class UsingEnumerator 44 | extends AtomicBoolean 45 | implements AsyncEnumerator, BiConsumer { 46 | 47 | final U resource; 48 | 49 | final AsyncEnumerator source; 50 | 51 | final Consumer release; 52 | 53 | T result; 54 | 55 | CompletableFuture completable; 56 | 57 | UsingEnumerator(U resource, AsyncEnumerator source, Consumer release) { 58 | this.resource = resource; 59 | this.source = source; 60 | this.release = release; 61 | } 62 | 63 | @Override 64 | public CompletionStage moveNext() { 65 | result = null; 66 | CompletableFuture cf = new CompletableFuture<>(); 67 | completable = cf; 68 | source.moveNext().whenComplete(this); 69 | return cf; 70 | } 71 | 72 | @Override 73 | public T current() { 74 | return result; 75 | } 76 | 77 | @Override 78 | public void cancel() { 79 | source.cancel(); 80 | cleanup(); 81 | } 82 | 83 | void cleanup() { 84 | if (compareAndSet(false, true)) { 85 | release.accept(resource); 86 | } 87 | } 88 | 89 | @Override 90 | public void accept(Boolean aBoolean, Throwable throwable) { 91 | if (throwable != null) { 92 | completable.completeExceptionally(throwable); 93 | cleanup(); 94 | return; 95 | } 96 | 97 | if (aBoolean) { 98 | result = source.current(); 99 | completable.complete(true); 100 | } else { 101 | completable.complete(false); 102 | cleanup(); 103 | } 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/CancelledEnumeratorException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import java.util.concurrent.CancellationException; 20 | 21 | final class CancelledEnumeratorException extends CancellationException { 22 | @Override 23 | public synchronized Throwable fillInStackTrace() { 24 | return this; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/GroupedAsyncEnumerable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | public interface GroupedAsyncEnumerable extends AsyncEnumerable { 20 | 21 | K key(); 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/SyncEmitter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | public interface SyncEmitter { 20 | 21 | void next(T item); 22 | 23 | void error(Throwable error); 24 | 25 | void stop(); 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/hu/akarnokd/asyncenum/ThrowableHelper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | /** 20 | * Utility class to work with Throwables. 21 | */ 22 | final class ThrowableHelper { 23 | 24 | private ThrowableHelper() { 25 | throw new IllegalStateException("No instances!"); 26 | } 27 | 28 | public static RuntimeException wrapOrThrow(Throwable ex) { 29 | if (ex instanceof RuntimeException) { 30 | return (RuntimeException)ex; 31 | } 32 | if (ex instanceof Error) { 33 | throw (Error)ex; 34 | } 35 | return new RuntimeException(ex); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncBlockingFirstOptionalTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.io.IOException; 22 | import java.util.NoSuchElementException; 23 | 24 | import static org.junit.Assert.*; 25 | 26 | public class AsyncBlockingFirstOptionalTest { 27 | 28 | @Test(expected = NoSuchElementException.class) 29 | public void empty() { 30 | AsyncEnumerable.empty().blockingFirstOptional().get(); 31 | } 32 | 33 | @Test 34 | public void simple() { 35 | Integer v = AsyncEnumerable.range(1, 5) 36 | .blockingFirstOptional() 37 | .get(); 38 | 39 | assertEquals(1, v.intValue()); 40 | } 41 | 42 | @Test 43 | public void interrupt() { 44 | Thread.currentThread().interrupt(); 45 | 46 | try { 47 | AsyncEnumerable.never().blockingFirstOptional(); 48 | fail("Should have thrown"); 49 | } catch (RuntimeException ex) { 50 | assertTrue("" + ex, ex.getCause() instanceof InterruptedException); 51 | } 52 | } 53 | 54 | @Test 55 | public void checkedException() { 56 | try { 57 | AsyncEnumerable.error(new IOException()).blockingFirstOptional(); 58 | fail("Should have thrown"); 59 | } catch (RuntimeException ex) { 60 | assertTrue("" + ex, ex.getCause() instanceof IOException); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncBlockingFirstTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.io.IOException; 22 | import java.util.NoSuchElementException; 23 | 24 | import static org.junit.Assert.assertTrue; 25 | import static org.junit.Assert.fail; 26 | 27 | public class AsyncBlockingFirstTest { 28 | 29 | @Test 30 | public void utilityClass() { 31 | TestHelper.checkUtility(AsyncBlockingFirst.class); 32 | } 33 | 34 | @Test(expected = NoSuchElementException.class) 35 | public void empty() { 36 | AsyncEnumerable.empty().blockingFirst(); 37 | } 38 | 39 | @Test 40 | public void interrupt() { 41 | Thread.currentThread().interrupt(); 42 | 43 | try { 44 | AsyncEnumerable.never().blockingFirst(); 45 | fail("Should have thrown"); 46 | } catch (RuntimeException ex) { 47 | assertTrue("" + ex, ex.getCause() instanceof InterruptedException); 48 | } 49 | } 50 | 51 | @Test 52 | public void checkedException() { 53 | try { 54 | AsyncEnumerable.error(new IOException()).blockingFirst(); 55 | fail("Should have thrown"); 56 | } catch (RuntimeException ex) { 57 | assertTrue("" + ex, ex.getCause() instanceof IOException); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncBlockingLastOptionalTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.io.IOException; 22 | import java.util.NoSuchElementException; 23 | import java.util.concurrent.*; 24 | 25 | import static org.junit.Assert.*; 26 | 27 | public class AsyncBlockingLastOptionalTest { 28 | 29 | @Test 30 | public void interrupted() { 31 | Thread.currentThread().interrupt(); 32 | 33 | try { 34 | AsyncEnumerable.never() 35 | .blockingLastOptional(); 36 | fail("Should have thrown"); 37 | } catch (RuntimeException ex) { 38 | assertTrue(ex.toString(), ex.getCause() instanceof InterruptedException); 39 | } 40 | } 41 | 42 | @Test(expected = NoSuchElementException.class) 43 | public void asyncEmpty() { 44 | ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); 45 | try { 46 | AsyncEnumerable.timer(200, TimeUnit.MILLISECONDS, executor) 47 | .filter(v -> false) 48 | .blockingLastOptional().get(); 49 | } finally { 50 | executor.shutdownNow(); 51 | } 52 | } 53 | 54 | @Test 55 | public void last() { 56 | assertEquals(5, 57 | AsyncEnumerable.range(1, 5) 58 | .blockingLastOptional().get().intValue()); 59 | } 60 | 61 | 62 | @Test 63 | public void checkedException() { 64 | try { 65 | AsyncEnumerable.error(new IOException()).blockingLastOptional(); 66 | fail("Should have thrown"); 67 | } catch (RuntimeException ex) { 68 | assertTrue("" + ex, ex.getCause() instanceof IOException); 69 | } 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncBlockingLastTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.util.NoSuchElementException; 22 | import java.util.concurrent.*; 23 | 24 | import static org.junit.Assert.assertTrue; 25 | import static org.junit.Assert.fail; 26 | 27 | public class AsyncBlockingLastTest { 28 | 29 | @Test 30 | public void interrupted() { 31 | Thread.currentThread().interrupt(); 32 | 33 | try { 34 | AsyncEnumerable.never() 35 | .blockingLast(); 36 | fail("Should have thrown"); 37 | } catch (RuntimeException ex) { 38 | assertTrue(ex.toString(), ex.getCause() instanceof InterruptedException); 39 | } 40 | } 41 | 42 | @Test(expected = NoSuchElementException.class) 43 | public void asyncEmpty() { 44 | ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); 45 | try { 46 | AsyncEnumerable.timer(200, TimeUnit.MILLISECONDS, executor) 47 | .filter(v -> false) 48 | .blockingLast(); 49 | } finally { 50 | executor.shutdownNow(); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncCharactersTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.util.*; 22 | 23 | import static org.junit.Assert.assertEquals; 24 | 25 | public class AsyncCharactersTest { 26 | 27 | @Test 28 | public void simple() { 29 | List list = AsyncEnumerable.characters("abcde") 30 | .toList() 31 | .blockingFirst(); 32 | 33 | assertEquals(Arrays.asList(97, 98, 99, 100, 101), list); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncCompletionStageTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.util.*; 22 | import java.util.concurrent.CompletableFuture; 23 | 24 | import static org.junit.Assert.assertEquals; 25 | 26 | public class AsyncCompletionStageTest { 27 | @Test 28 | public void simple() { 29 | 30 | List list = AsyncEnumerable.fromCompletionStage(CompletableFuture.completedStage(1)) 31 | .toList() 32 | .blockingFirst(); 33 | 34 | assertEquals(Collections.singletonList(1), list); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncComposeTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.util.*; 22 | 23 | import static org.junit.Assert.assertEquals; 24 | 25 | public class AsyncComposeTest { 26 | 27 | @Test 28 | public void compose() { 29 | List list = AsyncEnumerable.range(1, 5) 30 | .compose(AsyncEnumerable::toList) 31 | .to(AsyncEnumerable::blockingFirst); 32 | 33 | assertEquals(Arrays.asList(1, 2, 3, 4, 5), list); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncConcatArrayTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.util.*; 22 | 23 | import static org.junit.Assert.assertEquals; 24 | import static org.junit.Assert.assertSame; 25 | 26 | public class AsyncConcatArrayTest { 27 | 28 | @Test 29 | public void simple() throws Exception { 30 | List list = new ArrayList<>(); 31 | AsyncEnumerable.concatArray( 32 | AsyncEnumerable.range(1, 3), 33 | AsyncEnumerable.range(4, 2)) 34 | .forEach(list::add) 35 | .toCompletableFuture() 36 | .get(); 37 | 38 | assertEquals(Arrays.asList(1, 2, 3, 4, 5), list); 39 | } 40 | 41 | @Test 42 | public void simpleLong() throws Exception { 43 | List list = new ArrayList<>(); 44 | @SuppressWarnings("unchecked") 45 | AsyncEnumerable[] sources = new AsyncEnumerable[1_000_000]; 46 | for (int i = 1; i < sources.length - 1; i++) { 47 | sources[i] = AsyncEnumerable.empty(); 48 | } 49 | sources[0] = AsyncEnumerable.range(1, 3); 50 | sources[999_999] = AsyncEnumerable.range(4, 2); 51 | 52 | AsyncEnumerable.concatArray(sources) 53 | .forEach(list::add) 54 | .toCompletableFuture() 55 | .get(); 56 | 57 | assertEquals(Arrays.asList(1, 2, 3, 4, 5), list); 58 | } 59 | 60 | @Test 61 | public void startWith() { 62 | List list = 63 | AsyncEnumerable.range(1, 3) 64 | .startWith(AsyncEnumerable.range(4, 2)) 65 | .toList() 66 | .blockingFirst(); 67 | 68 | assertEquals(Arrays.asList(4, 5, 1, 2, 3), list); 69 | } 70 | 71 | @Test 72 | public void concatWith() { 73 | List list = 74 | AsyncEnumerable.range(1, 3) 75 | .concatWith(AsyncEnumerable.range(4, 2)) 76 | .toList() 77 | .blockingFirst(); 78 | 79 | assertEquals(Arrays.asList(1, 2, 3, 4, 5), list); 80 | } 81 | 82 | @Test 83 | public void emptyArray() { 84 | TestHelper.assertResult(AsyncEnumerable.concatArray()); 85 | } 86 | 87 | @Test 88 | public void cancelThenMove() { 89 | TestHelper.withExecutor(executor -> { 90 | for (int i = 0; i < 10000; i++) { 91 | AsyncEnumerator en = AsyncEnumerable.concatArray(AsyncEnumerable.range(1, 5)) 92 | .enumerator(); 93 | 94 | TestHelper.race(en::cancel, en::moveNext, executor); 95 | } 96 | }); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncConcataMapTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.util.*; 22 | 23 | import static org.junit.Assert.assertEquals; 24 | 25 | public class AsyncConcataMapTest { 26 | 27 | @Test 28 | public void simple() { 29 | List list = AsyncEnumerable.range(1, 5) 30 | .concatMap(v -> AsyncEnumerable.range(v, 2)) 31 | .toList() 32 | .blockingFirst(); 33 | 34 | assertEquals(Arrays.asList(1, 2, 2, 3, 3, 4, 4, 5, 5, 6), list); 35 | } 36 | 37 | @Test 38 | public void simpleLong() { 39 | List list = AsyncEnumerable.range(0, 1_000_000) 40 | .concatMap(AsyncEnumerable::just) 41 | .toList() 42 | .blockingFirst(); 43 | 44 | for (int i = 0; i < 1_000_000; i++) { 45 | assertEquals(i, list.get(i).intValue()); 46 | } 47 | } 48 | 49 | @Test 50 | public void simpleLongEmpty() { 51 | List list = AsyncEnumerable.range(0, 1_000_000) 52 | .concatMap(v -> AsyncEnumerable.empty()) 53 | .toList() 54 | .blockingFirst(); 55 | 56 | assertEquals(Collections.emptyList(), list); 57 | } 58 | 59 | @Test 60 | public void crossMap() { 61 | List list = AsyncEnumerable.range(0, 1_000) 62 | .concatMap(v -> AsyncEnumerable.range(v, 1000)) 63 | .toList() 64 | .blockingFirst(); 65 | for (int i = 0; i < 1_000; i++) { 66 | for (int j = i; j < i + 1000; j++) { 67 | assertEquals(j, list.get(i * 1_000 + (j - i)).intValue()); 68 | } 69 | } 70 | } 71 | 72 | @Test 73 | public void mainError() { 74 | TestHelper.assertFailure( 75 | AsyncEnumerable.error(new RuntimeException("forced failure")) 76 | .concatMap(v -> AsyncEnumerable.just(1)), 77 | RuntimeException.class, "forced failure" 78 | ); 79 | } 80 | 81 | @Test 82 | public void innerError() { 83 | TestHelper.assertFailure( 84 | AsyncEnumerable.range(1, 5) 85 | .concatMap(v -> AsyncEnumerable.error(new RuntimeException("forced failure"))), 86 | RuntimeException.class, "forced failure" 87 | ); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncDistinctTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.io.IOException; 22 | import java.util.HashSet; 23 | import java.util.concurrent.TimeUnit; 24 | 25 | public class AsyncDistinctTest { 26 | 27 | @Test 28 | public void simple() { 29 | TestHelper.assertResult( 30 | AsyncEnumerable.fromArray(1, 2, 3, 2, 1, 4, 5, 4, 5, 5) 31 | .distinct(), 32 | 1, 2, 3, 4, 5 33 | ); 34 | } 35 | 36 | @Test 37 | public void error() { 38 | TestHelper.assertFailure( 39 | AsyncEnumerable.error(new IOException()) 40 | .distinct(v -> v), 41 | IOException.class 42 | ); 43 | } 44 | 45 | @Test 46 | public void keySelector() { 47 | TestHelper.assertResult( 48 | AsyncEnumerable.range(1, 10) 49 | .distinct(k -> k & 3), 50 | 1, 2, 3, 4 51 | ); 52 | } 53 | 54 | @Test 55 | public void stops() { 56 | TestHelper.withScheduler(executor -> { 57 | TestHelper.assertResult( 58 | AsyncEnumerable.range(1, 1_000_000_000) 59 | .distinct(v -> v, IgnoringSet::new) 60 | .takeUntil(AsyncEnumerable.timer(100, TimeUnit.MILLISECONDS, executor)) 61 | .ignoreElements() 62 | .timeout(1, TimeUnit.SECONDS, executor) 63 | ); 64 | }); 65 | } 66 | 67 | @Test(timeout = 5000) 68 | public void cancelRace() { 69 | TestHelper.cancelRace(ae -> ae.distinct(v -> v, DuplicateSet::new)); 70 | } 71 | 72 | static final class IgnoringSet extends HashSet { 73 | 74 | @Override 75 | public boolean add(T t) { 76 | return true; 77 | } 78 | } 79 | 80 | static final class DuplicateSet extends HashSet { 81 | 82 | @Override 83 | public boolean add(T t) { 84 | return false; 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncDistinctUntilChangedTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.io.IOException; 22 | import java.util.Objects; 23 | 24 | public class AsyncDistinctUntilChangedTest { 25 | 26 | @Test 27 | public void simple() { 28 | TestHelper.assertResult( 29 | AsyncEnumerable.fromArray(1, 2, 2, 3, 3, 4, 4, 4, 5, 1, 2, 5) 30 | .distinctUntilChanged(), 31 | 1, 2, 3, 4, 5, 1, 2, 5 32 | ); 33 | } 34 | 35 | @Test 36 | public void error() { 37 | TestHelper.assertFailure( 38 | AsyncEnumerable.error(new IOException()) 39 | .distinctUntilChanged(v -> v), 40 | IOException.class 41 | ); 42 | } 43 | 44 | @Test 45 | public void cancelRace() { 46 | TestHelper.cancelRace(ae -> ae.distinctUntilChanged(v -> v, Objects::equals)); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncDoOnCancelTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.io.IOException; 22 | import java.util.concurrent.atomic.AtomicBoolean; 23 | 24 | import static org.junit.Assert.assertFalse; 25 | import static org.junit.Assert.assertTrue; 26 | 27 | public class AsyncDoOnCancelTest { 28 | 29 | @Test 30 | public void simple() { 31 | AtomicBoolean cancelled = new AtomicBoolean(); 32 | 33 | TestHelper.assertResult( 34 | AsyncEnumerable.range(1, 5) 35 | .doOnCancel(() -> cancelled.set(true)) 36 | .take(3), 37 | 1, 2, 3 38 | ); 39 | 40 | assertTrue(cancelled.get()); 41 | } 42 | 43 | 44 | @Test 45 | public void error() { 46 | AtomicBoolean cancelled = new AtomicBoolean(); 47 | 48 | TestHelper.assertFailure( 49 | AsyncEnumerable.error(new IOException()) 50 | .doOnCancel(() -> cancelled.set(true)) 51 | .take(3), 52 | IOException.class 53 | ); 54 | 55 | assertFalse(cancelled.get()); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncEmptyTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import static org.junit.Assert.assertNull; 22 | 23 | public class AsyncEmptyTest { 24 | 25 | 26 | @Test 27 | public void emptyNoCurrent() { 28 | assertNull(AsyncEmpty.INSTANCE.current()); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncEnumeratorHelperTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.util.concurrent.*; 22 | import java.util.concurrent.atomic.AtomicReference; 23 | 24 | import static org.junit.Assert.*; 25 | 26 | public class AsyncEnumeratorHelperTest { 27 | 28 | @Test 29 | public void doubleCancel() { 30 | AtomicReference> ref = new AtomicReference<>(); 31 | 32 | assertTrue(AsyncEnumeratorHelper.cancel(ref)); 33 | assertFalse(AsyncEnumeratorHelper.cancel(ref)); 34 | } 35 | 36 | @Test 37 | public void replaceRace() { 38 | TestHelper.withExecutor(executor -> { 39 | 40 | AtomicReference> ref = new AtomicReference<>(); 41 | 42 | for (int i = 0; i < 10000; i++) { 43 | Runnable r1 = () -> AsyncEnumeratorHelper.replace(ref, AsyncEmpty.INSTANCE); 44 | 45 | Runnable r2 = () -> AsyncEnumeratorHelper.cancel(ref); 46 | 47 | TestHelper.race(r1, r2, executor); 48 | 49 | assertTrue(AsyncEnumeratorHelper.isCancelled(ref.get())); 50 | } 51 | }); 52 | } 53 | 54 | 55 | @Test 56 | public void replaceRace2() { 57 | TestHelper.withExecutor(executor -> { 58 | 59 | AtomicReference> ref = new AtomicReference<>(); 60 | 61 | for (int i = 0; i < 10000; i++) { 62 | Runnable r1 = () -> AsyncEnumeratorHelper.replace(ref, AsyncEmpty.INSTANCE); 63 | 64 | Runnable r2 = () -> AsyncEnumeratorHelper.replace(ref, AsyncNever.INSTANCE); 65 | 66 | TestHelper.race(r1, r2, executor); 67 | } 68 | }); 69 | } 70 | 71 | @Test 72 | public void cancelledCurrentNull() { 73 | assertNull(AsyncEnumeratorHelper.CANCELLED.current()); 74 | } 75 | 76 | @Test 77 | public void cancelledMoveNext() throws InterruptedException { 78 | assertSame(AsyncEnumerable.CANCELLED, AsyncEnumeratorHelper.CANCELLED.moveNext()); 79 | } 80 | 81 | @Test 82 | public void cancelledCancel() { 83 | AsyncEnumeratorHelper.CANCELLED.cancel(); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncErrorTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import static org.junit.Assert.assertNull; 22 | 23 | public class AsyncErrorTest { 24 | 25 | @Test 26 | public void nullCurrent() { 27 | assertNull(AsyncEnumerable.error(new RuntimeException()).enumerator().current()); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncFilterTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.util.*; 22 | 23 | import static org.junit.Assert.assertEquals; 24 | 25 | public class AsyncFilterTest { 26 | 27 | @Test 28 | public void simple() { 29 | List list = AsyncEnumerable.range(1, 10) 30 | .filter(v -> v % 2 == 0) 31 | .toList() 32 | .blockingFirst(); 33 | 34 | assertEquals(Arrays.asList(2, 4, 6, 8, 10), list); 35 | } 36 | 37 | @Test 38 | public void error() { 39 | TestHelper.assertFailure( 40 | AsyncEnumerable.error(new RuntimeException("forced failure")) 41 | .filter(v -> true), 42 | RuntimeException.class, "forced failure" 43 | ); 44 | } 45 | } 46 | 47 | 48 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncFirstTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.io.IOException; 22 | 23 | public class AsyncFirstTest { 24 | 25 | @Test 26 | public void simple() { 27 | TestHelper.assertResult( 28 | AsyncEnumerable.range(1, 5) 29 | .first(), 30 | 1 31 | ); 32 | } 33 | 34 | 35 | @Test 36 | public void take() { 37 | TestHelper.assertResult( 38 | AsyncEnumerable.range(1, 5) 39 | .first() 40 | .take(1), 41 | 1 42 | ); 43 | } 44 | 45 | @Test 46 | public void empty() { 47 | TestHelper.assertResult( 48 | AsyncEnumerable.empty() 49 | .first() 50 | ); 51 | } 52 | 53 | @Test 54 | public void error() { 55 | TestHelper.assertFailure( 56 | AsyncEnumerable.error(new IOException()) 57 | .first(), 58 | IOException.class 59 | ); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncFlatMapTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.util.*; 22 | 23 | import static org.junit.Assert.assertEquals; 24 | 25 | public class AsyncFlatMapTest { 26 | 27 | @Test 28 | public void synchronous() throws Exception { 29 | List list = new ArrayList(); 30 | AsyncEnumerable.range(1, 5) 31 | .flatMap(v -> AsyncEnumerable.range(v, 2)) 32 | .forEach(list::add) 33 | .toCompletableFuture() 34 | .get(); 35 | 36 | // due to prefetch 1, the result is the breadth-first collection 37 | assertEquals(Arrays.asList(1, 2, 3, 4, 5, 2, 3, 4, 5, 6), list); 38 | } 39 | 40 | 41 | @Test 42 | public void synchronousTake() throws Exception { 43 | List list = 44 | AsyncEnumerable.range(1, 5) 45 | .flatMap(v -> AsyncEnumerable.range(v, 2)) 46 | .take(5) 47 | .toList() 48 | .blockingFirst(); 49 | 50 | // due to prefetch 1, the result is the breadth-first collection 51 | assertEquals(Arrays.asList(1, 2, 3, 4, 5), list); 52 | } 53 | 54 | @Test 55 | public void mainError() { 56 | TestHelper.assertFailure( 57 | AsyncEnumerable.error(new RuntimeException("forced failure")) 58 | .flatMap(v -> AsyncEnumerable.just(1)), 59 | RuntimeException.class, "forced failure" 60 | ); 61 | } 62 | 63 | @Test 64 | public void innerError() { 65 | TestHelper.assertFailure( 66 | AsyncEnumerable.range(1, 5) 67 | .flatMap(v -> AsyncEnumerable.error(new RuntimeException("forced failure"))), 68 | RuntimeException.class, "forced failure" 69 | ); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncForEachTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.util.concurrent.ExecutionException; 22 | 23 | import static org.junit.Assert.assertTrue; 24 | 25 | public class AsyncForEachTest { 26 | 27 | @Test 28 | public void error() throws InterruptedException { 29 | try { 30 | AsyncEnumerable.error(new RuntimeException("forced failure")) 31 | .forEach(v -> { 32 | }) 33 | .toCompletableFuture() 34 | .get(); 35 | } catch (ExecutionException ex) { 36 | assertTrue(ex.toString(), ex.getCause().getMessage().equals("forced failure")); 37 | } 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncFromArrayTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.util.*; 22 | 23 | import static org.junit.Assert.assertEquals; 24 | 25 | public class AsyncFromArrayTest { 26 | 27 | @Test 28 | public void simple() throws Exception { 29 | List list = new ArrayList<>(); 30 | AsyncEnumerable.fromArray(1, 2, 3, 4, 5) 31 | .forEach(list::add) 32 | .toCompletableFuture() 33 | .get(); 34 | 35 | assertEquals(Arrays.asList(1, 2, 3, 4, 5), list); 36 | } 37 | 38 | @Test 39 | public void take() { 40 | TestHelper.assertResult( 41 | AsyncEnumerable.fromArray(1, 2, 3, 4, 5) 42 | .take(3), 43 | 1, 2, 3 44 | ); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncFromCallableTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.io.IOException; 22 | 23 | public class AsyncFromCallableTest { 24 | 25 | @Test 26 | public void simple() { 27 | TestHelper.assertResult( 28 | AsyncEnumerable.fromCallable(() -> 1), 29 | 1); 30 | } 31 | 32 | @Test 33 | public void error() { 34 | TestHelper.assertFailure( 35 | AsyncEnumerable.fromCallable(() -> { throw new IOException(); }), 36 | IOException.class 37 | ); 38 | } 39 | 40 | @Test 41 | public void cancel() { 42 | AsyncEnumerable.fromCallable(() -> 1) 43 | .enumerator() 44 | .cancel(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncFromIterableTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.util.*; 22 | 23 | import static org.junit.Assert.assertEquals; 24 | 25 | public class AsyncFromIterableTest { 26 | 27 | @Test 28 | public void simple() throws Exception { 29 | List list = new ArrayList<>(); 30 | AsyncEnumerable.fromIterable(Arrays.asList(1, 2, 3, 4, 5)) 31 | .forEach(list::add) 32 | .toCompletableFuture() 33 | .get(); 34 | 35 | assertEquals(Arrays.asList(1, 2, 3, 4, 5), list); 36 | } 37 | 38 | 39 | @Test 40 | public void take() { 41 | TestHelper.assertResult( 42 | AsyncEnumerable.fromIterable(Arrays.asList(1, 2, 3, 4, 5)) 43 | .take(3), 44 | 1, 2, 3 45 | ); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncFromStreamTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.util.concurrent.atomic.AtomicBoolean; 22 | import java.util.stream.*; 23 | 24 | import static org.junit.Assert.assertEquals; 25 | import static org.junit.Assert.assertTrue; 26 | 27 | public class AsyncFromStreamTest { 28 | 29 | @Test 30 | public void simple() { 31 | TestHelper.assertResult( 32 | AsyncEnumerable.fromStream(IntStream.range(1, 1 + 5).boxed()), 33 | 1, 2, 3, 4, 5 34 | ); 35 | } 36 | 37 | @Test 38 | public void error() { 39 | Stream stream = IntStream.range(1, 1 + 5).boxed(); 40 | assertEquals(5, stream.count()); 41 | TestHelper.assertFailure( 42 | AsyncEnumerable.fromStream(stream), 43 | IllegalStateException.class 44 | ); 45 | } 46 | 47 | 48 | @Test 49 | public void close() { 50 | AtomicBoolean bool = new AtomicBoolean(); 51 | TestHelper.assertResult( 52 | AsyncEnumerable.fromStream(IntStream.range(1, 1 + 5).boxed() 53 | .onClose(() -> bool.set(true))), 54 | 1, 2, 3, 4, 5 55 | ); 56 | 57 | assertTrue(bool.get()); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncIgnoreElementsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.io.IOException; 22 | import java.util.concurrent.atomic.AtomicBoolean; 23 | 24 | import static org.junit.Assert.assertNull; 25 | import static org.junit.Assert.assertTrue; 26 | 27 | public class AsyncIgnoreElementsTest { 28 | 29 | @Test 30 | public void simple() { 31 | TestHelper.assertResult( 32 | AsyncEnumerable.range(1, 5) 33 | .ignoreElements() 34 | ); 35 | } 36 | 37 | @Test 38 | public void cancel() { 39 | AtomicBoolean cancelled = new AtomicBoolean(); 40 | AsyncEnumerable.never() 41 | .doOnCancel(() -> cancelled.set(true)) 42 | .ignoreElements() 43 | .enumerator() 44 | .cancel(); 45 | 46 | assertTrue(cancelled.get()); 47 | } 48 | 49 | @Test 50 | public void error() { 51 | TestHelper.assertFailure( 52 | AsyncEnumerable.error(new IOException()) 53 | .ignoreElements(), 54 | IOException.class 55 | ); 56 | } 57 | 58 | @Test 59 | public void nullCurrent() { 60 | assertNull(AsyncEnumerable.never().ignoreElements().enumerator().current()); 61 | } 62 | 63 | @Test(timeout = 5000) 64 | public void cancelRace() { 65 | TestHelper.cancelRace(AsyncEnumerable::ignoreElements); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncIntervalTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.util.*; 22 | import java.util.concurrent.*; 23 | 24 | import static org.junit.Assert.assertEquals; 25 | 26 | public class AsyncIntervalTest { 27 | 28 | @Test 29 | public void simple() { 30 | ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); 31 | try { 32 | List list = AsyncEnumerable.interval(1, TimeUnit.MILLISECONDS, executor) 33 | .take(5) 34 | .toList() 35 | .blockingFirst(); 36 | 37 | assertEquals(Arrays.asList(0L, 1L, 2L, 3L, 4L), list); 38 | } finally { 39 | executor.shutdownNow(); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncLastTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.io.IOException; 22 | 23 | public class AsyncLastTest { 24 | 25 | @Test 26 | public void simple() { 27 | TestHelper.assertResult( 28 | AsyncEnumerable.range(1, 5) 29 | .last(), 30 | 5 31 | ); 32 | } 33 | 34 | @Test 35 | public void take() { 36 | TestHelper.assertResult( 37 | AsyncEnumerable.range(1, 5) 38 | .last() 39 | .take(1), 40 | 5 41 | ); 42 | } 43 | 44 | @Test 45 | public void empty() { 46 | TestHelper.assertResult( 47 | AsyncEnumerable.empty() 48 | .last() 49 | ); 50 | } 51 | 52 | @Test 53 | public void error() { 54 | TestHelper.assertFailure( 55 | AsyncEnumerable.error(new IOException()) 56 | .last(), 57 | IOException.class 58 | ); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncMergeTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.util.*; 22 | 23 | import static org.junit.Assert.assertEquals; 24 | 25 | public class AsyncMergeTest { 26 | 27 | @Test 28 | public void simple() { 29 | 30 | List list = 31 | AsyncEnumerable.range(1, 3) 32 | .mergeWith(AsyncEnumerable.range(4, 2)) 33 | .toList() 34 | .blockingLast(); 35 | 36 | assertEquals(Arrays.asList(1, 4, 2, 5, 3), list); 37 | 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncNeverTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import static org.junit.Assert.assertNull; 22 | 23 | public class AsyncNeverTest { 24 | 25 | @Test 26 | public void nullCurrent() { 27 | assertNull(AsyncNever.INSTANCE.current()); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncObserveOnTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.io.IOException; 22 | import java.util.List; 23 | import java.util.concurrent.*; 24 | 25 | import static org.junit.Assert.assertEquals; 26 | import static org.junit.Assert.assertTrue; 27 | 28 | public class AsyncObserveOnTest { 29 | 30 | @Test 31 | public void simple() { 32 | ExecutorService exec = Executors.newSingleThreadExecutor(r -> new Thread(r, "CustomPool")); 33 | try { 34 | List list = AsyncEnumerable.range(1, 5) 35 | .observeOn(exec) 36 | .map(v -> v + " " + Thread.currentThread().getName()) 37 | .toList() 38 | .blockingFirst(); 39 | 40 | assertEquals(5, list.size()); 41 | for (String s : list) { 42 | assertTrue(s, s.contains("CustomPool")); 43 | } 44 | } finally { 45 | exec.shutdownNow(); 46 | } 47 | } 48 | 49 | @Test 50 | public void error() { 51 | TestHelper.withExecutor(exec -> { 52 | TestHelper.assertFailure( 53 | AsyncEnumerable.error(new IllegalArgumentException("forced failure")) 54 | .observeOn(exec) 55 | , IllegalArgumentException.class, "forced failure"); 56 | }); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncOnErrorResumeTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.io.IOException; 22 | import java.util.*; 23 | 24 | import static org.junit.Assert.assertEquals; 25 | 26 | public class AsyncOnErrorResumeTest { 27 | 28 | @Test 29 | public void simple() { 30 | List list = AsyncEnumerable.range(1, 5) 31 | .onErrorResume(v -> AsyncEnumerable.range(6, 5)) 32 | .toList() 33 | .blockingFirst(); 34 | 35 | assertEquals(Arrays.asList(1, 2, 3, 4, 5), list); 36 | } 37 | 38 | @Test 39 | public void withError() { 40 | List list = AsyncEnumerable.error(new IOException()) 41 | .onErrorResume(v -> AsyncEnumerable.range(6, 5)) 42 | .toList() 43 | .blockingFirst(); 44 | 45 | assertEquals(Arrays.asList(6, 7, 8, 9, 10), list); 46 | } 47 | 48 | @Test 49 | public void fallbackToError() { 50 | TestHelper.assertFailure( 51 | AsyncEnumerable.error(new RuntimeException("outer")) 52 | .onErrorResume(v -> AsyncEnumerable.error(new RuntimeException("inner"))), 53 | RuntimeException.class, "inner" 54 | ); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncRangeTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.util.*; 22 | 23 | import static org.junit.Assert.assertEquals; 24 | import static org.junit.Assert.assertTrue; 25 | 26 | public class AsyncRangeTest { 27 | 28 | @Test 29 | public void shortRange() throws Exception { 30 | runRange(10); 31 | } 32 | 33 | void runRange(int n) throws Exception { 34 | List list = new ArrayList<>(); 35 | Boolean result = AsyncEnumerable.range(1, n) 36 | .forEach(list::add) 37 | .toCompletableFuture() 38 | .get(); 39 | 40 | assertTrue(result); 41 | assertEquals(n, list.size()); 42 | 43 | for (int i = 1; i <= n; i++) { 44 | assertEquals(i, list.get(i - 1).intValue()); 45 | } 46 | } 47 | 48 | @Test 49 | public void longRange() throws Exception { 50 | runRange(1_000_000); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncReduceTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.io.IOException; 22 | 23 | public class AsyncReduceTest { 24 | 25 | @Test 26 | public void simple() { 27 | TestHelper.assertResult( 28 | AsyncEnumerable.range(1, 5) 29 | .reduce((a, b) -> a + b), 30 | 15 31 | ); 32 | } 33 | 34 | 35 | @Test 36 | public void simpleEmpty() { 37 | TestHelper.assertResult( 38 | AsyncEnumerable.empty() 39 | .reduce((a, b) -> a + b) 40 | ); 41 | } 42 | 43 | @Test 44 | public void error() { 45 | TestHelper.assertFailure( 46 | AsyncEnumerable.error(new IOException()) 47 | .reduce((a, b) -> a + b), 48 | IOException.class 49 | ); 50 | } 51 | 52 | @Test 53 | public void cancelRace() { 54 | TestHelper.cancelRace(ae -> ae.reduce((a, b) -> a + b)); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncReduceWithTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.io.IOException; 22 | 23 | public class AsyncReduceWithTest { 24 | 25 | @Test 26 | public void simple() { 27 | TestHelper.assertResult( 28 | AsyncEnumerable.range(1, 5) 29 | .reduce(() -> 10, (a, b) -> a + b), 30 | 25 31 | ); 32 | } 33 | 34 | 35 | @Test 36 | public void simpleEmpty() { 37 | TestHelper.assertResult( 38 | AsyncEnumerable.empty() 39 | .reduce(() -> 10, (a, b) -> a + b), 40 | 10 41 | ); 42 | } 43 | 44 | @Test 45 | public void error() { 46 | TestHelper.assertFailure( 47 | AsyncEnumerable.error(new IOException()) 48 | .reduce(() -> 10, (a, b) -> a + b), 49 | IOException.class 50 | ); 51 | } 52 | 53 | @Test 54 | public void cancelRace() { 55 | TestHelper.cancelRace(ae -> ae.reduce(() -> 0, (a, b) -> a + b)); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncRepeatCallableTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.io.IOException; 22 | 23 | public class AsyncRepeatCallableTest { 24 | 25 | @Test 26 | public void simple() { 27 | TestHelper.assertResult( 28 | AsyncEnumerable.repeatCallable(() -> 1).take(5), 29 | 1, 1, 1, 1, 1 30 | ); 31 | } 32 | 33 | @Test 34 | public void error() { 35 | TestHelper.assertFailure( 36 | AsyncEnumerable.repeatCallable(() -> { throw new IOException(); }), 37 | IOException.class 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncRepeatItemTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | public class AsyncRepeatItemTest { 22 | 23 | @Test 24 | public void simple() { 25 | TestHelper.assertResult( 26 | AsyncEnumerable.repeatItem(1).take(5), 27 | 1, 1, 1, 1, 1 28 | ); 29 | 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncRepeatTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.io.IOException; 22 | 23 | public class AsyncRepeatTest { 24 | 25 | @Test 26 | public void simple() { 27 | TestHelper.assertResult( 28 | AsyncEnumerable.just(1) 29 | .repeat(5), 30 | 1, 1, 1, 1, 1 31 | ); 32 | } 33 | 34 | @Test 35 | public void take() { 36 | TestHelper.assertResult( 37 | AsyncEnumerable.just(1) 38 | .repeat(5) 39 | .take(5), 40 | 1, 1, 1, 1, 1 41 | ); 42 | } 43 | 44 | @Test 45 | public void error() { 46 | TestHelper.assertFailure( 47 | AsyncEnumerable.error(new IOException()) 48 | .repeat(1), 49 | IOException.class 50 | ); 51 | } 52 | 53 | @Test 54 | public void stop() { 55 | TestHelper.assertResult( 56 | AsyncEnumerable.just(1) 57 | .repeat(() -> true), 58 | 1 59 | ); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncRepeatWhenTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.io.IOException; 22 | import java.util.concurrent.CompletableFuture; 23 | import java.util.concurrent.atomic.AtomicInteger; 24 | 25 | public class AsyncRepeatWhenTest { 26 | 27 | @Test 28 | public void simple() { 29 | TestHelper.assertResult( 30 | AsyncEnumerable.just(1) 31 | .repeatWhen(() -> CompletableFuture.completedFuture(true)) 32 | .take(5), 33 | 1, 1, 1, 1, 1 34 | ); 35 | } 36 | 37 | 38 | @Test 39 | public void withState() { 40 | TestHelper.assertResult( 41 | AsyncEnumerable.just(1) 42 | .repeatWhen(AtomicInteger::new, s -> CompletableFuture.completedFuture(s.incrementAndGet() < 5)) 43 | , 44 | 1, 1, 1, 1, 1 45 | ); 46 | } 47 | 48 | @Test 49 | public void mainError() { 50 | TestHelper.assertFailure( 51 | AsyncEnumerable.error(new IOException()) 52 | .repeatWhen(() -> CompletableFuture.completedStage(false)), 53 | IOException.class 54 | ); 55 | } 56 | 57 | @Test 58 | public void completerError() { 59 | TestHelper.assertFailure( 60 | AsyncEnumerable.just(1) 61 | .repeatWhen(() -> CompletableFuture.failedStage(new IOException())), 62 | IOException.class 63 | ); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncRetryTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.io.IOException; 22 | import java.util.concurrent.atomic.AtomicInteger; 23 | 24 | public class AsyncRetryTest { 25 | 26 | @Test 27 | public void simple() { 28 | TestHelper.assertResult( 29 | AsyncEnumerable.just(1) 30 | .retry(5), 31 | 1 32 | ); 33 | } 34 | 35 | @Test 36 | public void take() { 37 | TestHelper.assertResult( 38 | AsyncEnumerable.repeatItem(1) 39 | .retry(5) 40 | .take(5), 41 | 1, 1, 1, 1, 1 42 | ); 43 | } 44 | 45 | @Test 46 | public void error() { 47 | TestHelper.assertFailure( 48 | AsyncEnumerable.error(new IOException()) 49 | .retry(1), 50 | IOException.class 51 | ); 52 | } 53 | 54 | @Test 55 | public void stop() { 56 | TestHelper.assertResult( 57 | AsyncEnumerable.just(1) 58 | .retry(e -> false), 59 | 1 60 | ); 61 | } 62 | 63 | @Test 64 | public void rightError() { 65 | AtomicInteger count = new AtomicInteger(); 66 | 67 | TestHelper.assertResult( 68 | AsyncEnumerable.defer(() -> { 69 | if (count.getAndIncrement() == 0) { 70 | return AsyncEnumerable.error(new IOException()); 71 | } 72 | return AsyncEnumerable.range(1, 5); 73 | }) 74 | .retry(1), 75 | 1, 2, 3, 4, 5 76 | ); 77 | } 78 | 79 | @Test 80 | public void wrongError() { 81 | AtomicInteger count = new AtomicInteger(); 82 | 83 | TestHelper.assertFailure( 84 | AsyncEnumerable.error(new IOException()) 85 | .retry(e -> e instanceof RuntimeException), 86 | IOException.class 87 | ); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncRetryWhenTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.io.IOException; 22 | import java.util.concurrent.CompletableFuture; 23 | import java.util.concurrent.atomic.AtomicInteger; 24 | 25 | public class AsyncRetryWhenTest { 26 | 27 | @Test 28 | public void simple() { 29 | TestHelper.assertResult( 30 | AsyncEnumerable.range(1, 5) 31 | .retryWhen(e -> CompletableFuture.completedStage(false)) 32 | , 33 | 1, 2, 3, 4, 5 34 | ); 35 | } 36 | 37 | @Test 38 | public void take() { 39 | TestHelper.assertResult( 40 | AsyncEnumerable.range(1, 5) 41 | .retryWhen(e -> CompletableFuture.completedStage(false)) 42 | .take(3), 43 | 1, 2, 3 44 | ); 45 | } 46 | 47 | @Test 48 | public void error() { 49 | TestHelper.assertResult( 50 | AsyncEnumerable.error(new IOException()) 51 | .retryWhen(AtomicInteger::new, (s, e) -> CompletableFuture.completedStage(s.incrementAndGet() < 5)) 52 | ); 53 | } 54 | 55 | @Test 56 | public void completerFails() { 57 | TestHelper.assertFailure( 58 | AsyncEnumerable.error(new IOException()) 59 | .retryWhen(AtomicInteger::new, (s, e) -> CompletableFuture.failedStage(e)), 60 | IOException.class 61 | ); 62 | 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncSkipLastTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.io.IOException; 22 | 23 | public class AsyncSkipLastTest { 24 | 25 | @Test 26 | public void simple() { 27 | TestHelper.assertResult( 28 | AsyncEnumerable.range(1, 5) 29 | .skipLast(2), 30 | 1, 2, 3 31 | ); 32 | } 33 | 34 | @Test 35 | public void simpleNoSkip() { 36 | TestHelper.assertResult( 37 | AsyncEnumerable.range(1, 5) 38 | .skipLast(0), 39 | 1, 2, 3, 4, 5 40 | ); 41 | } 42 | 43 | 44 | @Test 45 | public void simpleNoSkipAll() { 46 | TestHelper.assertResult( 47 | AsyncEnumerable.range(1, 5) 48 | .skipLast(6) 49 | ); 50 | } 51 | 52 | @Test 53 | public void error() { 54 | TestHelper.assertFailure( 55 | AsyncEnumerable.error(new IOException()) 56 | .skipLast(2), 57 | IOException.class 58 | ); 59 | } 60 | 61 | @Test 62 | public void cancelRace() { 63 | TestHelper.cancelRace(ae -> ae.skipLast(2)); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncSkipTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.util.*; 22 | 23 | import static hu.akarnokd.asyncenum.TestHelper.assertFailure; 24 | import static hu.akarnokd.asyncenum.TestHelper.assertResult; 25 | import static org.junit.Assert.assertEquals; 26 | 27 | public class AsyncSkipTest { 28 | 29 | @Test 30 | public void simple() throws Exception { 31 | List list = new ArrayList<>(); 32 | AsyncEnumerable.range(1, 5) 33 | .skip(3) 34 | .forEach(list::add) 35 | .toCompletableFuture() 36 | .get(); 37 | 38 | assertEquals(Arrays.asList(4, 5), list); 39 | } 40 | 41 | @Test 42 | public void sorter() throws Exception { 43 | List list = new ArrayList<>(); 44 | AsyncEnumerable.range(1, 2) 45 | .skip(3) 46 | .forEach(list::add) 47 | .toCompletableFuture() 48 | .get(); 49 | 50 | assertEquals(Collections.emptyList(), list); 51 | } 52 | 53 | @Test 54 | public void simpleLong() throws Exception { 55 | List list = new ArrayList<>(); 56 | AsyncEnumerable.range(1, 1_000_000) 57 | .skip(999_997) 58 | .forEach(list::add) 59 | .toCompletableFuture() 60 | .get(); 61 | 62 | assertEquals(Arrays.asList(999_998, 999_999, 1_000_000), list); 63 | } 64 | 65 | @Test 66 | public void error() { 67 | assertFailure(AsyncEnumerable.error(new RuntimeException("forced failure")) 68 | .skip(1), 69 | RuntimeException.class, "forced failure" 70 | ); 71 | } 72 | 73 | @Test 74 | public void take() { 75 | assertResult( 76 | AsyncEnumerable.range(1, 5).skip(1).take(3), 77 | 2, 3, 4 78 | ); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncSkipWhileTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.io.IOException; 22 | 23 | public class AsyncSkipWhileTest { 24 | 25 | @Test 26 | public void simple() { 27 | TestHelper.assertResult( 28 | AsyncEnumerable.range(1, 5) 29 | .skipWhile(v -> v < 3), 30 | 3, 4, 5 31 | ); 32 | } 33 | 34 | 35 | @Test 36 | public void take() { 37 | TestHelper.assertResult( 38 | AsyncEnumerable.range(1, 5) 39 | .skipWhile(v -> v < 3) 40 | .take(2), 41 | 3, 4 42 | ); 43 | } 44 | 45 | @Test 46 | public void simpleSkipAll() { 47 | TestHelper.assertResult( 48 | AsyncEnumerable.range(1, 5) 49 | .skipWhile(v -> v < 6) 50 | ); 51 | } 52 | 53 | 54 | @Test 55 | public void error() { 56 | TestHelper.assertFailure( 57 | AsyncEnumerable.error(new IOException()) 58 | .skipWhile(v -> v < 5), 59 | IOException.class 60 | ); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncSubscribeOnTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.util.List; 22 | import java.util.concurrent.*; 23 | import java.util.concurrent.atomic.AtomicReference; 24 | 25 | import static org.junit.Assert.assertEquals; 26 | import static org.junit.Assert.assertTrue; 27 | 28 | public class AsyncSubscribeOnTest { 29 | 30 | @Test 31 | public void simple() { 32 | ExecutorService exec = Executors.newSingleThreadExecutor(r -> new Thread(r, "CustomPool")); 33 | try { 34 | List list = AsyncEnumerable.defer(() -> 35 | AsyncEnumerable.just(Thread.currentThread().getName())) 36 | .subscribeOn(exec) 37 | .toList() 38 | .blockingFirst(); 39 | 40 | assertEquals(1, list.size()); 41 | for (String s : list) { 42 | assertTrue(s, s.contains("CustomPool")); 43 | } 44 | } finally { 45 | exec.shutdownNow(); 46 | } 47 | } 48 | 49 | @Test 50 | public void cancel() { 51 | TestHelper.withScheduler(executor ->{ 52 | AtomicReference> f = new AtomicReference<>(); 53 | AsyncEnumerable.range(1, 5) 54 | .subscribeOn(r -> { 55 | f.set(executor.schedule(r, 100, TimeUnit.MILLISECONDS)); 56 | }) 57 | .enumerator() 58 | .cancel(); 59 | 60 | try { 61 | f.get().get(); 62 | } catch (InterruptedException | ExecutionException e) { 63 | e.printStackTrace(); 64 | } 65 | }); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncSwitchIfEmptyTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.io.IOException; 22 | 23 | public class AsyncSwitchIfEmptyTest { 24 | 25 | @Test 26 | public void nonEmpty() { 27 | TestHelper.assertResult( 28 | AsyncEnumerable.range(1, 5) 29 | .switchIfEmpty(AsyncEnumerable.range(6, 5)), 30 | 1, 2, 3, 4, 5 31 | ); 32 | } 33 | 34 | @Test 35 | public void empty() { 36 | TestHelper.assertResult( 37 | AsyncEnumerable.empty() 38 | .switchIfEmpty(AsyncEnumerable.range(6, 5)), 39 | 6, 7, 8, 9, 10 40 | ); 41 | } 42 | 43 | 44 | @Test 45 | public void nonEmptyTake() { 46 | TestHelper.assertResult( 47 | AsyncEnumerable.range(1, 5) 48 | .switchIfEmpty(AsyncEnumerable.range(6, 5)) 49 | .take(3), 50 | 1, 2, 3 51 | ); 52 | } 53 | 54 | @Test 55 | public void emptyTake() { 56 | TestHelper.assertResult( 57 | AsyncEnumerable.empty() 58 | .switchIfEmpty(AsyncEnumerable.range(6, 5)) 59 | .take(3), 60 | 6, 7, 8 61 | ); 62 | } 63 | 64 | 65 | @Test 66 | public void emptyEmpty() { 67 | TestHelper.assertResult( 68 | AsyncEnumerable.empty() 69 | .switchIfEmpty(AsyncEnumerable.empty()) 70 | ); 71 | } 72 | 73 | @Test 74 | public void error() { 75 | TestHelper.assertFailure( 76 | AsyncEnumerable.error(new IOException()) 77 | .switchIfEmpty(AsyncEnumerable.range(1, 5)), 78 | IOException.class 79 | ); 80 | } 81 | 82 | 83 | @Test 84 | public void emptyError() { 85 | TestHelper.assertFailure( 86 | AsyncEnumerable.empty() 87 | .switchIfEmpty(AsyncEnumerable.error(new IOException())), 88 | IOException.class 89 | ); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncTakeLastTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.io.IOException; 22 | 23 | public class AsyncTakeLastTest { 24 | 25 | @Test 26 | public void simple() { 27 | TestHelper.assertResult( 28 | AsyncEnumerable.range(1, 5) 29 | .takeLast(2), 30 | 4, 5 31 | ); 32 | } 33 | 34 | @Test 35 | public void simpleEmpty() { 36 | TestHelper.assertResult( 37 | AsyncEnumerable.range(1, 5) 38 | .takeLast(0) 39 | ); 40 | } 41 | 42 | @Test 43 | public void simpleEmptySource() { 44 | TestHelper.assertResult( 45 | AsyncEnumerable.empty() 46 | .takeLast(2) 47 | ); 48 | } 49 | 50 | @Test 51 | public void simpleAll() { 52 | TestHelper.assertResult( 53 | AsyncEnumerable.range(1, 5) 54 | .takeLast(5), 55 | 1, 2, 3, 4, 5 56 | ); 57 | } 58 | 59 | 60 | @Test 61 | public void simpleAll2() { 62 | TestHelper.assertResult( 63 | AsyncEnumerable.range(1, 5) 64 | .takeLast(6), 65 | 1, 2, 3, 4, 5 66 | ); 67 | } 68 | 69 | @Test 70 | public void error() { 71 | TestHelper.assertFailure( 72 | AsyncEnumerable.error(new IOException()) 73 | .takeLast(2), 74 | IOException.class 75 | ); 76 | } 77 | 78 | @Test 79 | public void cancelRace() { 80 | TestHelper.cancelRace(ae -> ae.takeLast(2)); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncTakeTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.util.*; 22 | 23 | import static org.junit.Assert.assertEquals; 24 | 25 | public class AsyncTakeTest { 26 | 27 | @Test 28 | public void simple() throws Exception { 29 | List list = new ArrayList<>(); 30 | AsyncEnumerable.range(1, 5) 31 | .take(3) 32 | .forEach(list::add) 33 | .toCompletableFuture() 34 | .get(); 35 | 36 | assertEquals(Arrays.asList(1, 2, 3), list); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncTakeUntilPredicateTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.io.IOException; 22 | import java.util.concurrent.atomic.AtomicBoolean; 23 | 24 | import static org.junit.Assert.assertTrue; 25 | 26 | public class AsyncTakeUntilPredicateTest { 27 | 28 | @Test 29 | public void simple() { 30 | AtomicBoolean cancelled = new AtomicBoolean(); 31 | 32 | TestHelper.assertResult( 33 | AsyncEnumerable.range(1, 5) 34 | .doOnCancel(() -> cancelled.set(true)) 35 | .takeUntil(v -> v == 4), 36 | 1, 2, 3, 4 37 | ); 38 | 39 | assertTrue(cancelled.get()); 40 | } 41 | 42 | @Test 43 | public void take() { 44 | TestHelper.assertResult( 45 | AsyncEnumerable.range(1, 5) 46 | .takeUntil(v -> v == 4) 47 | .take(3), 48 | 1, 2, 3 49 | ); 50 | } 51 | 52 | 53 | @Test 54 | public void empty() { 55 | TestHelper.assertResult( 56 | AsyncEnumerable.empty() 57 | .takeUntil(v -> v == 4) 58 | ); 59 | } 60 | 61 | @Test 62 | public void error() { 63 | TestHelper.assertFailure( 64 | AsyncEnumerable.error(new IOException()) 65 | .takeUntil(v -> false), 66 | IOException.class 67 | ); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncTakeWhileTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.io.IOException; 22 | 23 | public class AsyncTakeWhileTest { 24 | 25 | @Test 26 | public void simple() { 27 | TestHelper.assertResult( 28 | AsyncEnumerable.range(1, 5) 29 | .takeWhile(v -> v < 4), 30 | 1, 2, 3 31 | ); 32 | } 33 | 34 | @Test 35 | public void all() { 36 | TestHelper.assertResult( 37 | AsyncEnumerable.range(1, 5) 38 | .takeWhile(v -> v < 6), 39 | 1, 2, 3, 4, 5 40 | ); 41 | } 42 | 43 | @Test 44 | public void take() { 45 | TestHelper.assertResult( 46 | AsyncEnumerable.range(1, 5) 47 | .takeWhile(v -> v < 4) 48 | .take(2), 49 | 1, 2 50 | ); 51 | } 52 | 53 | @Test 54 | public void error() { 55 | TestHelper.assertFailure( 56 | AsyncEnumerable.error(new IOException()) 57 | .takeWhile(v -> v < 4), 58 | IOException.class 59 | ); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncTimeoutTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.util.*; 22 | import java.util.concurrent.*; 23 | 24 | import static org.junit.Assert.assertEquals; 25 | 26 | public class AsyncTimeoutTest { 27 | 28 | @Test 29 | public void noTimeout() { 30 | ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); 31 | try { 32 | List list = AsyncEnumerable.range(1, 5) 33 | .timeout(1, TimeUnit.MINUTES, scheduler) 34 | .toList() 35 | .blockingFirst() 36 | ; 37 | 38 | assertEquals(Arrays.asList(1, 2, 3, 4, 5), list); 39 | } finally { 40 | scheduler.shutdownNow(); 41 | } 42 | } 43 | 44 | @Test 45 | public void withTimeout() { 46 | ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); 47 | try { 48 | List list = AsyncEnumerable.never() 49 | .timeout(100, TimeUnit.MILLISECONDS, scheduler, AsyncEnumerable.range(1, 5)) 50 | .toList() 51 | .blockingFirst() 52 | ; 53 | 54 | assertEquals(Arrays.asList(1, 2, 3, 4, 5), list); 55 | } finally { 56 | scheduler.shutdownNow(); 57 | } 58 | } 59 | 60 | @Test 61 | public void error() { 62 | TestHelper.withScheduler(executor -> { 63 | TestHelper.assertFailure( 64 | AsyncEnumerable.error(new RuntimeException("forced failure")) 65 | .timeout(1, TimeUnit.MINUTES, executor), 66 | RuntimeException.class, "forced failure" 67 | ); 68 | }); 69 | } 70 | 71 | @Test 72 | public void timeoutNoFallback() { 73 | TestHelper.withScheduler(executor -> { 74 | TestHelper.assertFailure( 75 | AsyncEnumerable.never() 76 | .timeout(1, TimeUnit.MILLISECONDS, executor), 77 | TimeoutException.class 78 | ); 79 | }); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncTimerTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.util.*; 22 | import java.util.concurrent.*; 23 | 24 | import static org.junit.Assert.assertEquals; 25 | 26 | public class AsyncTimerTest { 27 | 28 | @Test 29 | public void simple() { 30 | ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); 31 | try { 32 | List list = 33 | AsyncEnumerable.timer(100, TimeUnit.MILLISECONDS, scheduler) 34 | .toList() 35 | .blockingFirst(); 36 | 37 | assertEquals(Collections.singletonList(0L), list); 38 | } finally { 39 | scheduler.shutdownNow(); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncToFlowPublisherTckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.reactivestreams.tck.TestEnvironment; 20 | import org.reactivestreams.tck.flow.FlowPublisherVerification; 21 | import org.testng.annotations.Test; 22 | 23 | import java.util.concurrent.Flow; 24 | 25 | @Test 26 | public class AsyncToFlowPublisherTckTest extends FlowPublisherVerification { 27 | 28 | public AsyncToFlowPublisherTckTest() { 29 | super(new TestEnvironment()); 30 | } 31 | 32 | @Override 33 | public Flow.Publisher createFlowPublisher(long elements) { 34 | return AsyncEnumerable.range(0, (int)elements).toFlowPublisher(); 35 | } 36 | 37 | @Override 38 | public Flow.Publisher createFailedFlowPublisher() { 39 | return AsyncEnumerable.error(new RuntimeException()).toFlowPublisher(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncUsingTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.io.IOException; 22 | import java.util.concurrent.atomic.AtomicReference; 23 | 24 | import static org.junit.Assert.assertEquals; 25 | 26 | public class AsyncUsingTest { 27 | 28 | @Test 29 | public void since() { 30 | AtomicReference res = new AtomicReference<>(); 31 | TestHelper.assertResult( 32 | AsyncEnumerable.using(() -> 1, v -> AsyncEnumerable.range(v, 5), res::set), 33 | 1, 2, 3, 4, 5 34 | ); 35 | 36 | assertEquals(1, res.get().intValue()); 37 | } 38 | 39 | 40 | @Test 41 | public void take() { 42 | AtomicReference res = new AtomicReference<>(); 43 | TestHelper.assertResult( 44 | AsyncEnumerable.using(() -> 1, v -> AsyncEnumerable.range(v, 5), res::set).take(3), 45 | 1, 2, 3 46 | ); 47 | 48 | assertEquals(1, res.get().intValue()); 49 | } 50 | 51 | @Test 52 | public void error() { 53 | AtomicReference res = new AtomicReference<>(); 54 | 55 | TestHelper.assertFailure( 56 | AsyncEnumerable.using(() -> 1, v -> AsyncEnumerable.error(new IOException("" + v)), res::set), 57 | IOException.class, "1" 58 | ); 59 | 60 | assertEquals(1, res.get().intValue()); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/AsyncZipArrayTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | import java.util.*; 22 | 23 | import static org.junit.Assert.assertEquals; 24 | 25 | public class AsyncZipArrayTest { 26 | 27 | @Test 28 | public void simple() { 29 | List list = AsyncEnumerable.zipArray( 30 | a -> (Integer)a[0] + (Integer)a[1], 31 | AsyncEnumerable.range(1, 5), 32 | AsyncEnumerable.range(10, 5) 33 | ) 34 | .toList() 35 | .blockingFirst(); 36 | 37 | assertEquals(Arrays.asList(10 + 1, 11 + 2, 12 + 3, 13 + 4, 14 + 5), list); 38 | } 39 | 40 | 41 | @Test 42 | public void oneShorter() { 43 | List list = AsyncEnumerable.zipArray( 44 | a -> (Integer)a[0] + (Integer)a[1], 45 | AsyncEnumerable.range(1, 4), 46 | AsyncEnumerable.range(10, 5) 47 | ) 48 | .toList() 49 | .blockingFirst(); 50 | 51 | assertEquals(Arrays.asList(10 + 1, 11 + 2, 12 + 3, 13 + 4), list); 52 | } 53 | 54 | @Test 55 | public void twoShorter() { 56 | List list = AsyncEnumerable.zipArray( 57 | a -> (Integer)a[0] + (Integer)a[1], 58 | AsyncEnumerable.range(1, 5), 59 | AsyncEnumerable.range(10, 4) 60 | ) 61 | .toList() 62 | .blockingFirst(); 63 | 64 | assertEquals(Arrays.asList(10 + 1, 11 + 2, 12 + 3, 13 + 4), list); 65 | } 66 | 67 | @Test 68 | public void simpleWith() { 69 | List list = AsyncEnumerable.range(1, 5) 70 | .zipWith(AsyncEnumerable.range(10, 5), (a, b) -> a + b) 71 | .toList() 72 | .blockingFirst(); 73 | 74 | assertEquals(Arrays.asList(10 + 1, 11 + 2, 12 + 3, 13 + 4, 14 + 5), list); 75 | } 76 | 77 | @Test 78 | public void oneError() { 79 | TestHelper.assertFailure( 80 | AsyncEnumerable.just(1).zipWith(AsyncEnumerable.error(new RuntimeException("forced failure")), (a, b) -> a), 81 | RuntimeException.class, "forced failure" 82 | ); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/test/java/hu/akarnokd/asyncenum/ThrowableHelperTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.asyncenum; 18 | 19 | import org.junit.Test; 20 | 21 | public class ThrowableHelperTest { 22 | 23 | @Test 24 | public void utilityClass() { 25 | TestHelper.checkUtility(ThrowableHelper.class); 26 | } 27 | 28 | @Test(expected = InternalError.class) 29 | public void rethrowError() { 30 | ThrowableHelper.wrapOrThrow(new InternalError()); 31 | } 32 | } 33 | --------------------------------------------------------------------------------