From 3a0c57aec46ef35c8b9b60014705f51336952060 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A8=D0=B0=D1=85=D0=BE=D0=B2=20=D0=90=D0=BB=D0=B5=D0=BA?= =?UTF-8?q?=D1=81=D0=B0=D0=BD=D0=B4=D1=80?= Date: Sun, 19 Feb 2023 00:16:37 +0300 Subject: [PATCH 01/58] Init commit --- wiki-game-common/pom.xml | 23 +++++++++++++++++++ .../src/main/java/point/rar/Main.java | 7 ++++++ .../java/point/rar/adapter/WikiRequest.java | 4 ++++ .../java/point/rar/adapter/WikiResponse.java | 4 ++++ .../src/main/java/point/rar/domain/Page.java | 4 ++++ .../java/point/rar/domain/model/Link.java | 4 ++++ .../point/rar/domain/model/PageLinks.java | 6 +++++ .../rar/domain/model/QueryBacklinks.java | 7 ++++++ .../point/rar/domain/model/QueryLinks.java | 8 +++++++ .../domain/model/WikiBacklinksResponse.java | 4 ++++ .../rar/domain/model/WikiLinksResponse.java | 4 ++++ 11 files changed, 75 insertions(+) create mode 100644 wiki-game-common/pom.xml create mode 100644 wiki-game-common/src/main/java/point/rar/Main.java create mode 100644 wiki-game-common/src/main/java/point/rar/adapter/WikiRequest.java create mode 100644 wiki-game-common/src/main/java/point/rar/adapter/WikiResponse.java create mode 100644 wiki-game-common/src/main/java/point/rar/domain/Page.java create mode 100644 wiki-game-common/src/main/java/point/rar/domain/model/Link.java create mode 100644 wiki-game-common/src/main/java/point/rar/domain/model/PageLinks.java create mode 100644 wiki-game-common/src/main/java/point/rar/domain/model/QueryBacklinks.java create mode 100644 wiki-game-common/src/main/java/point/rar/domain/model/QueryLinks.java create mode 100644 wiki-game-common/src/main/java/point/rar/domain/model/WikiBacklinksResponse.java create mode 100644 wiki-game-common/src/main/java/point/rar/domain/model/WikiLinksResponse.java diff --git a/wiki-game-common/pom.xml b/wiki-game-common/pom.xml new file mode 100644 index 0000000..845f08c --- /dev/null +++ b/wiki-game-common/pom.xml @@ -0,0 +1,23 @@ + + + 4.0.0 + + point.rar + wiki-game-common + 1.0-SNAPSHOT + + 19 + 19 + + + + + org.asynchttpclient + async-http-client + 3.0.0.Beta1 + + + + \ No newline at end of file diff --git a/wiki-game-common/src/main/java/point/rar/Main.java b/wiki-game-common/src/main/java/point/rar/Main.java new file mode 100644 index 0000000..23ff025 --- /dev/null +++ b/wiki-game-common/src/main/java/point/rar/Main.java @@ -0,0 +1,7 @@ +package point.rar; + +public class Main { + public static void main(String[] args) { + System.out.println("Hello world!"); + } +} \ No newline at end of file diff --git a/wiki-game-common/src/main/java/point/rar/adapter/WikiRequest.java b/wiki-game-common/src/main/java/point/rar/adapter/WikiRequest.java new file mode 100644 index 0000000..aa61c84 --- /dev/null +++ b/wiki-game-common/src/main/java/point/rar/adapter/WikiRequest.java @@ -0,0 +1,4 @@ +package point.rar.adapter; + +public record WikiRequest() { +} diff --git a/wiki-game-common/src/main/java/point/rar/adapter/WikiResponse.java b/wiki-game-common/src/main/java/point/rar/adapter/WikiResponse.java new file mode 100644 index 0000000..472d73c --- /dev/null +++ b/wiki-game-common/src/main/java/point/rar/adapter/WikiResponse.java @@ -0,0 +1,4 @@ +package point.rar.adapter; + +public record WikiResponse() { +} diff --git a/wiki-game-common/src/main/java/point/rar/domain/Page.java b/wiki-game-common/src/main/java/point/rar/domain/Page.java new file mode 100644 index 0000000..56e0fcc --- /dev/null +++ b/wiki-game-common/src/main/java/point/rar/domain/Page.java @@ -0,0 +1,4 @@ +package point.rar.domain; + +public record Page() { +} diff --git a/wiki-game-common/src/main/java/point/rar/domain/model/Link.java b/wiki-game-common/src/main/java/point/rar/domain/model/Link.java new file mode 100644 index 0000000..dea5afe --- /dev/null +++ b/wiki-game-common/src/main/java/point/rar/domain/model/Link.java @@ -0,0 +1,4 @@ +package point.rar.domain.model; + +record Link(String title){ +} diff --git a/wiki-game-common/src/main/java/point/rar/domain/model/PageLinks.java b/wiki-game-common/src/main/java/point/rar/domain/model/PageLinks.java new file mode 100644 index 0000000..4d00040 --- /dev/null +++ b/wiki-game-common/src/main/java/point/rar/domain/model/PageLinks.java @@ -0,0 +1,6 @@ +package point.rar.domain.model; + +import java.util.List; + +record PageLinks(List links) { +} diff --git a/wiki-game-common/src/main/java/point/rar/domain/model/QueryBacklinks.java b/wiki-game-common/src/main/java/point/rar/domain/model/QueryBacklinks.java new file mode 100644 index 0000000..83bac8a --- /dev/null +++ b/wiki-game-common/src/main/java/point/rar/domain/model/QueryBacklinks.java @@ -0,0 +1,7 @@ +package point.rar.domain.model; + +import java.util.List; + +record QueryBacklinks(List backlinks){ + +} diff --git a/wiki-game-common/src/main/java/point/rar/domain/model/QueryLinks.java b/wiki-game-common/src/main/java/point/rar/domain/model/QueryLinks.java new file mode 100644 index 0000000..c2714b9 --- /dev/null +++ b/wiki-game-common/src/main/java/point/rar/domain/model/QueryLinks.java @@ -0,0 +1,8 @@ +package point.rar.domain.model; + +import point.rar.domain.model.PageLinks; + +import java.util.Map; + +record QueryLinks(Map pages){ +} diff --git a/wiki-game-common/src/main/java/point/rar/domain/model/WikiBacklinksResponse.java b/wiki-game-common/src/main/java/point/rar/domain/model/WikiBacklinksResponse.java new file mode 100644 index 0000000..45ab8ea --- /dev/null +++ b/wiki-game-common/src/main/java/point/rar/domain/model/WikiBacklinksResponse.java @@ -0,0 +1,4 @@ +package point.rar.domain.model; + +record WikiBacklinksResponse(QueryBacklinks query) { +} diff --git a/wiki-game-common/src/main/java/point/rar/domain/model/WikiLinksResponse.java b/wiki-game-common/src/main/java/point/rar/domain/model/WikiLinksResponse.java new file mode 100644 index 0000000..475740e --- /dev/null +++ b/wiki-game-common/src/main/java/point/rar/domain/model/WikiLinksResponse.java @@ -0,0 +1,4 @@ +package point.rar.domain.model; + +record WikiLinksResponse(QueryLinks query) { +} \ No newline at end of file From 8777f8efb93c99e42437ce2d3294670a4d1db95b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A8=D0=B0=D1=85=D0=BE=D0=B2=20=D0=90=D0=BB=D0=B5=D0=BA?= =?UTF-8?q?=D1=81=D0=B0=D0=BD=D0=B4=D1=80?= Date: Sun, 19 Feb 2023 00:39:27 +0300 Subject: [PATCH 02/58] Init commit kotlin --- wiki-game-coroutines/build.gradle.kts | 31 +++ .../gradle/wrapper/gradle-wrapper.properties | 5 + wiki-game-coroutines/gradlew | 240 ++++++++++++++++++ wiki-game-coroutines/gradlew.bat | 91 +++++++ wiki-game-coroutines/settings.gradle.kts | 2 + .../src/main/java/point/rar/Main.kt | 6 + 6 files changed, 375 insertions(+) create mode 100644 wiki-game-coroutines/build.gradle.kts create mode 100644 wiki-game-coroutines/gradle/wrapper/gradle-wrapper.properties create mode 100755 wiki-game-coroutines/gradlew create mode 100644 wiki-game-coroutines/gradlew.bat create mode 100644 wiki-game-coroutines/settings.gradle.kts create mode 100644 wiki-game-coroutines/src/main/java/point/rar/Main.kt diff --git a/wiki-game-coroutines/build.gradle.kts b/wiki-game-coroutines/build.gradle.kts new file mode 100644 index 0000000..11747ea --- /dev/null +++ b/wiki-game-coroutines/build.gradle.kts @@ -0,0 +1,31 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + id("java") + kotlin("jvm") version "1.8.10" +} + +group = "point.rar" +version = "1.0-SNAPSHOT" + +repositories { + mavenCentral() +} + +dependencies { + testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.1") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.1") + implementation(kotlin("stdlib-jdk8")) +} + +tasks.getByName("test") { + useJUnitPlatform() +} +val compileKotlin: KotlinCompile by tasks +compileKotlin.kotlinOptions { + jvmTarget = "1.8" +} +val compileTestKotlin: KotlinCompile by tasks +compileTestKotlin.kotlinOptions { + jvmTarget = "1.8" +} \ No newline at end of file diff --git a/wiki-game-coroutines/gradle/wrapper/gradle-wrapper.properties b/wiki-game-coroutines/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..070cb70 --- /dev/null +++ b/wiki-game-coroutines/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/wiki-game-coroutines/gradlew b/wiki-game-coroutines/gradlew new file mode 100755 index 0000000..a69d9cb --- /dev/null +++ b/wiki-game-coroutines/gradlew @@ -0,0 +1,240 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +APP_NAME="Gradle" +APP_BASE_NAME=${0##*/} + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/wiki-game-coroutines/gradlew.bat b/wiki-game-coroutines/gradlew.bat new file mode 100644 index 0000000..f127cfd --- /dev/null +++ b/wiki-game-coroutines/gradlew.bat @@ -0,0 +1,91 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/wiki-game-coroutines/settings.gradle.kts b/wiki-game-coroutines/settings.gradle.kts new file mode 100644 index 0000000..18f01dd --- /dev/null +++ b/wiki-game-coroutines/settings.gradle.kts @@ -0,0 +1,2 @@ +rootProject.name = "wiki-game-coroutines" + diff --git a/wiki-game-coroutines/src/main/java/point/rar/Main.kt b/wiki-game-coroutines/src/main/java/point/rar/Main.kt new file mode 100644 index 0000000..cfafbd8 --- /dev/null +++ b/wiki-game-coroutines/src/main/java/point/rar/Main.kt @@ -0,0 +1,6 @@ +package point.rar + + +fun main(args: Array) { + println("Hello world!") +} \ No newline at end of file From 8a12ec8883e6b580030bf06268fe06da84f3379f Mon Sep 17 00:00:00 2001 From: eqimd Date: Sun, 19 Feb 2023 18:02:49 +0300 Subject: [PATCH 03/58] Add ktor version with getting links and backlinks --- wiki-game-coroutines/build.gradle.kts | 14 ++++ .../src/main/java/point/rar/Main.kt | 10 ++- .../wiki/data/source/WikiRemoteDataSource.kt | 7 ++ .../java/point/rar/wiki/domain/model/Link.kt | 8 +++ .../point/rar/wiki/domain/model/PageLinks.kt | 8 +++ .../rar/wiki/domain/model/QueryBacklinks.kt | 8 +++ .../point/rar/wiki/domain/model/QueryLinks.kt | 8 +++ .../domain/model/WikiBacklinksResponse.kt | 8 +++ .../wiki/domain/model/WikiLinksResponse.kt | 8 +++ .../wiki/remote/WikiRemoteDataSourceImpl.kt | 67 +++++++++++++++++++ 10 files changed, 144 insertions(+), 2 deletions(-) create mode 100644 wiki-game-coroutines/src/main/java/point/rar/wiki/data/source/WikiRemoteDataSource.kt create mode 100644 wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/Link.kt create mode 100644 wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/PageLinks.kt create mode 100644 wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/QueryBacklinks.kt create mode 100644 wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/QueryLinks.kt create mode 100644 wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/WikiBacklinksResponse.kt create mode 100644 wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/WikiLinksResponse.kt create mode 100644 wiki-game-coroutines/src/main/java/point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt diff --git a/wiki-game-coroutines/build.gradle.kts b/wiki-game-coroutines/build.gradle.kts index 11747ea..0bbc84c 100644 --- a/wiki-game-coroutines/build.gradle.kts +++ b/wiki-game-coroutines/build.gradle.kts @@ -3,6 +3,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { id("java") kotlin("jvm") version "1.8.10" + kotlin("plugin.serialization") version "1.8.10" } group = "point.rar" @@ -16,6 +17,19 @@ dependencies { testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.1") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.1") implementation(kotlin("stdlib-jdk8")) + + val ktor_version = "2.2.3" + implementation("io.ktor:ktor-client-core:$ktor_version") + implementation("io.ktor:ktor-client-cio:$ktor_version") + implementation("io.ktor:ktor-client-content-negotiation:$ktor_version") + implementation("io.ktor:ktor-serialization-kotlinx-json:$ktor_version") + + val slf4j_version = "2.0.6" + implementation("org.slf4j:slf4j-api:$slf4j_version") + implementation("org.slf4j:slf4j-simple:$slf4j_version") + + val kotlinx_serialization_json_version = "1.4.1" + implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinx_serialization_json_version") } tasks.getByName("test") { diff --git a/wiki-game-coroutines/src/main/java/point/rar/Main.kt b/wiki-game-coroutines/src/main/java/point/rar/Main.kt index cfafbd8..71646ab 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/Main.kt +++ b/wiki-game-coroutines/src/main/java/point/rar/Main.kt @@ -1,6 +1,12 @@ package point.rar +import point.rar.wiki.data.source.WikiRemoteDataSource +import point.rar.wiki.remote.WikiRemoteDataSourceImpl -fun main(args: Array) { - println("Hello world!") +suspend fun main(args: Array) { + val wikiRemoteDataSource: WikiRemoteDataSource = WikiRemoteDataSourceImpl() + + println( + wikiRemoteDataSource.getLinksByTitle("Coroutine") + ) } \ No newline at end of file diff --git a/wiki-game-coroutines/src/main/java/point/rar/wiki/data/source/WikiRemoteDataSource.kt b/wiki-game-coroutines/src/main/java/point/rar/wiki/data/source/WikiRemoteDataSource.kt new file mode 100644 index 0000000..a79d761 --- /dev/null +++ b/wiki-game-coroutines/src/main/java/point/rar/wiki/data/source/WikiRemoteDataSource.kt @@ -0,0 +1,7 @@ +package point.rar.wiki.data.source + +interface WikiRemoteDataSource { + suspend fun getLinksByTitle(title: String): List + + suspend fun getBacklinksByTitle(title: String): List +} \ No newline at end of file diff --git a/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/Link.kt b/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/Link.kt new file mode 100644 index 0000000..8adc63a --- /dev/null +++ b/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/Link.kt @@ -0,0 +1,8 @@ +package point.rar.wiki.domain.model + +import kotlinx.serialization.Serializable + +@Serializable +data class Link( + val title: String, +) diff --git a/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/PageLinks.kt b/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/PageLinks.kt new file mode 100644 index 0000000..371f6d6 --- /dev/null +++ b/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/PageLinks.kt @@ -0,0 +1,8 @@ +package point.rar.wiki.domain.model + +import kotlinx.serialization.Serializable + +@Serializable +data class PageLinks( + val links: List +) diff --git a/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/QueryBacklinks.kt b/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/QueryBacklinks.kt new file mode 100644 index 0000000..2cdd376 --- /dev/null +++ b/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/QueryBacklinks.kt @@ -0,0 +1,8 @@ +package point.rar.wiki.domain.model + +import kotlinx.serialization.Serializable + +@Serializable +data class QueryBacklinks( + val backlinks: List, +) diff --git a/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/QueryLinks.kt b/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/QueryLinks.kt new file mode 100644 index 0000000..bbc0dd0 --- /dev/null +++ b/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/QueryLinks.kt @@ -0,0 +1,8 @@ +package point.rar.wiki.domain.model + +import kotlinx.serialization.Serializable + +@Serializable +data class QueryLinks( + val pages: Map +) diff --git a/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/WikiBacklinksResponse.kt b/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/WikiBacklinksResponse.kt new file mode 100644 index 0000000..b4ba23c --- /dev/null +++ b/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/WikiBacklinksResponse.kt @@ -0,0 +1,8 @@ +package point.rar.wiki.domain.model + +import kotlinx.serialization.Serializable + +@Serializable +data class WikiBacklinksResponse( + val query: QueryBacklinks, +) diff --git a/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/WikiLinksResponse.kt b/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/WikiLinksResponse.kt new file mode 100644 index 0000000..a3cc428 --- /dev/null +++ b/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/WikiLinksResponse.kt @@ -0,0 +1,8 @@ +package point.rar.wiki.domain.model + +import kotlinx.serialization.Serializable + +@Serializable +data class WikiLinksResponse( + val query: QueryLinks +) \ No newline at end of file diff --git a/wiki-game-coroutines/src/main/java/point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt b/wiki-game-coroutines/src/main/java/point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt new file mode 100644 index 0000000..9d0e42e --- /dev/null +++ b/wiki-game-coroutines/src/main/java/point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt @@ -0,0 +1,67 @@ +package point.rar.wiki.remote + +import io.ktor.client.HttpClient +import io.ktor.client.call.body +import io.ktor.client.engine.cio.CIO +import io.ktor.client.plugins.contentnegotiation.ContentNegotiation +import io.ktor.client.request.get +import io.ktor.client.request.parameter +import io.ktor.serialization.kotlinx.json.json +import kotlinx.serialization.json.Json +import point.rar.wiki.data.source.WikiRemoteDataSource +import point.rar.wiki.domain.model.WikiBacklinksResponse +import point.rar.wiki.domain.model.WikiLinksResponse + +class WikiRemoteDataSourceImpl : WikiRemoteDataSource { + companion object Parameter { + val URL = "https://en.wikipedia.org/w/api.php" + } + + + private val client: HttpClient = HttpClient(CIO) { + install(ContentNegotiation) { + json(Json { + ignoreUnknownKeys = true + }) + } + } + + override suspend fun getLinksByTitle(title: String): List { + val request = client.get(URL) { + parameter("action", "query") + parameter("titles", title) + parameter("prop", "links") + parameter("pllimit", "max") + parameter("format", "json") + parameter("plnamespace", 0) + } + + val wikiLinksResponse: WikiLinksResponse = request.body() + + return wikiLinksResponse + .query + .pages + .values + .first() + .links + .map { it.title } + } + + override suspend fun getBacklinksByTitle(title: String): List { + val request = client.get(URL) { + parameter("action", "query") + parameter("bltitle", title) + parameter("list", "backlinks") + parameter("bllimit", "max") + parameter("format", "json") + parameter("blnamespace", 0) + } + + val wikiBacklinksResponse: WikiBacklinksResponse = request.body() + + return wikiBacklinksResponse + .query + .backlinks + .map { it.title } + } +} \ No newline at end of file From 37cc4698acdbeecac7ae6d255b9f6b11f0900669 Mon Sep 17 00:00:00 2001 From: eqimd Date: Fri, 3 Mar 2023 22:49:59 +0300 Subject: [PATCH 04/58] Add dumb version --- wiki-game-coroutines/build.gradle.kts | 6 ++ .../src/main/java/point/rar/Main.kt | 13 ++- .../point/rar/game/repository/WikiGame.kt | 5 ++ .../rar/game/repository/WikiGameDumbImpl.kt | 81 +++++++++++++++++++ .../java/point/rar/wiki/domain/model/Page.kt | 3 + .../point/rar/wiki/domain/model/PageLinks.kt | 2 +- .../wiki/remote/WikiRemoteDataSourceImpl.kt | 58 ++++++++----- 7 files changed, 142 insertions(+), 26 deletions(-) create mode 100644 wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGame.kt create mode 100644 wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt create mode 100644 wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/Page.kt diff --git a/wiki-game-coroutines/build.gradle.kts b/wiki-game-coroutines/build.gradle.kts index 0bbc84c..2c84f20 100644 --- a/wiki-game-coroutines/build.gradle.kts +++ b/wiki-game-coroutines/build.gradle.kts @@ -30,8 +30,14 @@ dependencies { val kotlinx_serialization_json_version = "1.4.1" implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinx_serialization_json_version") + + val resilience4jVersion = "2.0.0" + implementation("io.github.resilience4j:resilience4j-kotlin:${resilience4jVersion}") + implementation("io.github.resilience4j:resilience4j-ratelimiter:${resilience4jVersion}") + implementation("io.github.resilience4j:resilience4j-retry:${resilience4jVersion}") } + tasks.getByName("test") { useJUnitPlatform() } diff --git a/wiki-game-coroutines/src/main/java/point/rar/Main.kt b/wiki-game-coroutines/src/main/java/point/rar/Main.kt index 71646ab..11d2fcd 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/Main.kt +++ b/wiki-game-coroutines/src/main/java/point/rar/Main.kt @@ -1,12 +1,11 @@ package point.rar -import point.rar.wiki.data.source.WikiRemoteDataSource -import point.rar.wiki.remote.WikiRemoteDataSourceImpl +import point.rar.game.repository.WikiGame +import point.rar.game.repository.WikiGameDumbImpl -suspend fun main(args: Array) { - val wikiRemoteDataSource: WikiRemoteDataSource = WikiRemoteDataSourceImpl() +fun main(args: Array) { + val wikiGame: WikiGame = WikiGameDumbImpl() - println( - wikiRemoteDataSource.getLinksByTitle("Coroutine") - ) + val path = wikiGame.play("Java (programming language)", "Philosophy", maxDepth = 4) + println(path) } \ No newline at end of file diff --git a/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGame.kt b/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGame.kt new file mode 100644 index 0000000..0f60b09 --- /dev/null +++ b/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGame.kt @@ -0,0 +1,5 @@ +package point.rar.game.repository + +interface WikiGame { + fun play(startPageTitle: String, endPageTitle: String, maxDepth: Int = 11): Result> +} \ No newline at end of file diff --git a/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt b/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt new file mode 100644 index 0000000..474dceb --- /dev/null +++ b/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt @@ -0,0 +1,81 @@ +package point.rar.game.repository + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.CoroutineStart +import kotlinx.coroutines.cancel +import kotlinx.coroutines.cancelChildren +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.launch +import kotlinx.coroutines.newFixedThreadPoolContext +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.withContext +import point.rar.wiki.data.source.WikiRemoteDataSource +import point.rar.wiki.domain.model.Page +import point.rar.wiki.remote.WikiRemoteDataSourceImpl +import java.util.concurrent.ConcurrentHashMap +import kotlin.coroutines.coroutineContext + +class WikiGameDumbImpl : WikiGame { + private val wikiRemoteDataSource: WikiRemoteDataSource = WikiRemoteDataSourceImpl() + + override fun play(startPageTitle: String, endPageTitle: String, maxDepth: Int): Result> = runBlocking { + val visitedPages: Set = ConcurrentHashMap.newKeySet() + val resChannel = Channel>() + val scope = CoroutineScope(coroutineContext) + + val startPage = Page(startPageTitle, null) + scope.launch { + processPage(startPage, endPageTitle, 0, maxDepth, visitedPages, resChannel, scope) + } + + val resPage = resChannel.receive() + coroutineContext.cancelChildren() + + val endPage = resPage.getOrNull() ?: return@runBlocking Result.failure(resPage.exceptionOrNull()!!) + val path = mutableListOf() + + var curPg = endPage + while (curPg.parentPage != null) { + path.add(curPg.title) + curPg = curPg.parentPage!! + } + path.add(startPage.title) + + return@runBlocking Result.success(path.reversed()) + } + + private suspend fun processPage( + page: Page, + endPageTitle: String, + curDepth: Int, + maxDepth: Int, + visitedPages: Set, + resChannel: Channel>, + coroutineScope: CoroutineScope + ) { + if (visitedPages.contains(page.title)) { + return + } + + if (page.title == endPageTitle) { + resChannel.send(Result.success(page)) + return + } + + if (curDepth == maxDepth) { + resChannel.send(Result.failure(RuntimeException("Depth is reached"))) + return + } + + println("Started for ${page.title}, depth = $curDepth") + val links = wikiRemoteDataSource.getLinksByTitle(page.title) + links.forEach { + // Creates new scope because we don't want to wait for all the coroutines to complete + coroutineScope.launch { + processPage(Page(it, page), endPageTitle, curDepth + 1, maxDepth, visitedPages, resChannel, coroutineScope) + } + } + + } +} \ No newline at end of file diff --git a/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/Page.kt b/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/Page.kt new file mode 100644 index 0000000..579c302 --- /dev/null +++ b/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/Page.kt @@ -0,0 +1,3 @@ +package point.rar.wiki.domain.model + +data class Page(val title: String, val parentPage: Page?) diff --git a/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/PageLinks.kt b/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/PageLinks.kt index 371f6d6..92f3826 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/PageLinks.kt +++ b/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/PageLinks.kt @@ -4,5 +4,5 @@ import kotlinx.serialization.Serializable @Serializable data class PageLinks( - val links: List + val links: List? = null ) diff --git a/wiki-game-coroutines/src/main/java/point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt b/wiki-game-coroutines/src/main/java/point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt index 9d0e42e..0bca952 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt +++ b/wiki-game-coroutines/src/main/java/point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt @@ -17,8 +17,19 @@ class WikiRemoteDataSourceImpl : WikiRemoteDataSource { val URL = "https://en.wikipedia.org/w/api.php" } +// private val rateLimiterConfig = RateLimiterConfig +// .custom() +// .limitForPeriod(25) +// .limitRefreshPeriod(Duration.ofSeconds(2)) +// .timeoutDuration(Duration.ofDays(10000)) +// .build() +// private val rateLimiterRegistry = RateLimiterRegistry.of(rateLimiterConfig) +// private val rateLimiter = rateLimiterRegistry.rateLimiter("rate limiter") private val client: HttpClient = HttpClient(CIO) { + engine { + maxConnectionsCount = 25 + } install(ContentNegotiation) { json(Json { ignoreUnknownKeys = true @@ -27,24 +38,12 @@ class WikiRemoteDataSourceImpl : WikiRemoteDataSource { } override suspend fun getLinksByTitle(title: String): List { - val request = client.get(URL) { - parameter("action", "query") - parameter("titles", title) - parameter("prop", "links") - parameter("pllimit", "max") - parameter("format", "json") - parameter("plnamespace", 0) - } - - val wikiLinksResponse: WikiLinksResponse = request.body() - - return wikiLinksResponse - .query - .pages - .values - .first() - .links - .map { it.title } + return _getLinksByTitle(title) +// val links = rateLimiter.executeSuspendFunction { +// _getLinksByTitle(title) +// } +// +// return links } override suspend fun getBacklinksByTitle(title: String): List { @@ -64,4 +63,27 @@ class WikiRemoteDataSourceImpl : WikiRemoteDataSource { .backlinks .map { it.title } } + + private suspend fun _getLinksByTitle(title: String): List { + val response = client.get(URL) { + parameter("action", "query") + parameter("titles", title) + parameter("prop", "links") + parameter("pllimit", "max") + parameter("format", "json") + parameter("plnamespace", 0) + } + + val wikiLinksResponse: WikiLinksResponse = response.body() + + val links = wikiLinksResponse + .query + .pages + .values + .first() + .links + ?.map { it.title } ?: emptyList() + + return links + } } \ No newline at end of file From cfeb3b12d2b68ab705985722d91f399e82761a9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A8=D0=B0=D1=85=D0=BE=D0=B2=20=D0=90=D0=BB=D0=B5=D0=BA?= =?UTF-8?q?=D1=81=D0=B0=D0=BD=D0=B4=D1=80?= Date: Fri, 3 Mar 2023 23:40:49 +0300 Subject: [PATCH 05/58] Add0 rateLimiter --- .../src/main/java/point/rar/Main.kt | 4 +- .../rar/game/repository/WikiGameDumbImpl.kt | 6 ++- .../wiki/remote/WikiRemoteDataSourceImpl.kt | 37 ++++++++++--------- 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/wiki-game-coroutines/src/main/java/point/rar/Main.kt b/wiki-game-coroutines/src/main/java/point/rar/Main.kt index 11d2fcd..1f29124 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/Main.kt +++ b/wiki-game-coroutines/src/main/java/point/rar/Main.kt @@ -6,6 +6,8 @@ import point.rar.game.repository.WikiGameDumbImpl fun main(args: Array) { val wikiGame: WikiGame = WikiGameDumbImpl() - val path = wikiGame.play("Java (programming language)", "Philosophy", maxDepth = 4) + val start = System.nanoTime() + val path = wikiGame.play("Бакуган", "Библия", maxDepth = 6) + println((System.nanoTime() - start) / 1_000_000) println(path) } \ No newline at end of file diff --git a/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt b/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt index 474dceb..17f36e4 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt +++ b/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt @@ -20,7 +20,7 @@ class WikiGameDumbImpl : WikiGame { private val wikiRemoteDataSource: WikiRemoteDataSource = WikiRemoteDataSourceImpl() override fun play(startPageTitle: String, endPageTitle: String, maxDepth: Int): Result> = runBlocking { - val visitedPages: Set = ConcurrentHashMap.newKeySet() + val visitedPages: MutableSet = ConcurrentHashMap.newKeySet() val resChannel = Channel>() val scope = CoroutineScope(coroutineContext) @@ -42,6 +42,7 @@ class WikiGameDumbImpl : WikiGame { } path.add(startPage.title) + println(visitedPages.size) return@runBlocking Result.success(path.reversed()) } @@ -50,13 +51,14 @@ class WikiGameDumbImpl : WikiGame { endPageTitle: String, curDepth: Int, maxDepth: Int, - visitedPages: Set, + visitedPages: MutableSet, resChannel: Channel>, coroutineScope: CoroutineScope ) { if (visitedPages.contains(page.title)) { return } + visitedPages.add(page.title) if (page.title == endPageTitle) { resChannel.send(Result.success(page)) diff --git a/wiki-game-coroutines/src/main/java/point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt b/wiki-game-coroutines/src/main/java/point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt index 0bca952..eb67e8c 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt +++ b/wiki-game-coroutines/src/main/java/point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt @@ -1,5 +1,8 @@ package point.rar.wiki.remote +import io.github.resilience4j.kotlin.ratelimiter.executeSuspendFunction +import io.github.resilience4j.ratelimiter.RateLimiterConfig +import io.github.resilience4j.ratelimiter.RateLimiterRegistry import io.ktor.client.HttpClient import io.ktor.client.call.body import io.ktor.client.engine.cio.CIO @@ -11,25 +14,24 @@ import kotlinx.serialization.json.Json import point.rar.wiki.data.source.WikiRemoteDataSource import point.rar.wiki.domain.model.WikiBacklinksResponse import point.rar.wiki.domain.model.WikiLinksResponse +import java.time.Duration class WikiRemoteDataSourceImpl : WikiRemoteDataSource { companion object Parameter { - val URL = "https://en.wikipedia.org/w/api.php" + val URL = "https://ru.wikipedia.org/w/api.php" } -// private val rateLimiterConfig = RateLimiterConfig -// .custom() -// .limitForPeriod(25) -// .limitRefreshPeriod(Duration.ofSeconds(2)) -// .timeoutDuration(Duration.ofDays(10000)) -// .build() -// private val rateLimiterRegistry = RateLimiterRegistry.of(rateLimiterConfig) -// private val rateLimiter = rateLimiterRegistry.rateLimiter("rate limiter") + private val rateLimiterConfig = RateLimiterConfig + .custom() + .limitForPeriod(1) + .limitRefreshPeriod(Duration.ofMillis(5)) + .timeoutDuration(Duration.ofDays(10000)) + .build() + + private val rateLimiterRegistry = RateLimiterRegistry.of(rateLimiterConfig) + private val rateLimiter = rateLimiterRegistry.rateLimiter("rate limiter") private val client: HttpClient = HttpClient(CIO) { - engine { - maxConnectionsCount = 25 - } install(ContentNegotiation) { json(Json { ignoreUnknownKeys = true @@ -38,12 +40,11 @@ class WikiRemoteDataSourceImpl : WikiRemoteDataSource { } override suspend fun getLinksByTitle(title: String): List { - return _getLinksByTitle(title) -// val links = rateLimiter.executeSuspendFunction { -// _getLinksByTitle(title) -// } -// -// return links +// return _getLinksByTitle(title) + val links = rateLimiter.executeSuspendFunction { + _getLinksByTitle(title) + } + return links } override suspend fun getBacklinksByTitle(title: String): List { From d8d8a7e607027f564eccd9e5022e7415b42e7397 Mon Sep 17 00:00:00 2001 From: eqimd Date: Fri, 3 Mar 2023 23:44:43 +0300 Subject: [PATCH 06/58] Add received responses count --- .../rar/game/repository/WikiGameDumbImpl.kt | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt b/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt index 17f36e4..ffc6c6d 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt +++ b/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt @@ -17,10 +17,15 @@ import java.util.concurrent.ConcurrentHashMap import kotlin.coroutines.coroutineContext class WikiGameDumbImpl : WikiGame { + companion object { + private const val REQUEST_SENT = 1 + private const val RESPONSE_RECEIVED = 2 + } + private val wikiRemoteDataSource: WikiRemoteDataSource = WikiRemoteDataSourceImpl() override fun play(startPageTitle: String, endPageTitle: String, maxDepth: Int): Result> = runBlocking { - val visitedPages: MutableSet = ConcurrentHashMap.newKeySet() + val visitedPages: MutableMap = ConcurrentHashMap() val resChannel = Channel>() val scope = CoroutineScope(coroutineContext) @@ -42,7 +47,8 @@ class WikiGameDumbImpl : WikiGame { } path.add(startPage.title) - println(visitedPages.size) + val pagesWithResponseCount = visitedPages.entries.filter { it.value == RESPONSE_RECEIVED }.count() + println("Received responses from $pagesWithResponseCount pages") return@runBlocking Result.success(path.reversed()) } @@ -51,14 +57,14 @@ class WikiGameDumbImpl : WikiGame { endPageTitle: String, curDepth: Int, maxDepth: Int, - visitedPages: MutableSet, + visitedPages: MutableMap, resChannel: Channel>, coroutineScope: CoroutineScope ) { if (visitedPages.contains(page.title)) { return } - visitedPages.add(page.title) + visitedPages[page.title] = REQUEST_SENT if (page.title == endPageTitle) { resChannel.send(Result.success(page)) @@ -72,6 +78,9 @@ class WikiGameDumbImpl : WikiGame { println("Started for ${page.title}, depth = $curDepth") val links = wikiRemoteDataSource.getLinksByTitle(page.title) + + visitedPages[page.title] = RESPONSE_RECEIVED + links.forEach { // Creates new scope because we don't want to wait for all the coroutines to complete coroutineScope.launch { From 955e83e3f08f44bf1a55ad0ca1b9e4ad9b19ca8d Mon Sep 17 00:00:00 2001 From: eqimd Date: Fri, 3 Mar 2023 23:51:31 +0300 Subject: [PATCH 07/58] Take out serialization --- .../point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/wiki-game-coroutines/src/main/java/point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt b/wiki-game-coroutines/src/main/java/point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt index eb67e8c..596426e 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt +++ b/wiki-game-coroutines/src/main/java/point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt @@ -40,11 +40,7 @@ class WikiRemoteDataSourceImpl : WikiRemoteDataSource { } override suspend fun getLinksByTitle(title: String): List { -// return _getLinksByTitle(title) - val links = rateLimiter.executeSuspendFunction { - _getLinksByTitle(title) - } - return links + return _getLinksByTitle(title) } override suspend fun getBacklinksByTitle(title: String): List { @@ -66,7 +62,8 @@ class WikiRemoteDataSourceImpl : WikiRemoteDataSource { } private suspend fun _getLinksByTitle(title: String): List { - val response = client.get(URL) { + val response = rateLimiter.executeSuspendFunction { + client.get(URL) { parameter("action", "query") parameter("titles", title) parameter("prop", "links") @@ -74,6 +71,7 @@ class WikiRemoteDataSourceImpl : WikiRemoteDataSource { parameter("format", "json") parameter("plnamespace", 0) } + } val wikiLinksResponse: WikiLinksResponse = response.body() From 46c801c008259c2618ea958c99d1d125af2030b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A8=D0=B0=D1=85=D0=BE=D0=B2=20=D0=90=D0=BB=D0=B5=D0=BA?= =?UTF-8?q?=D1=81=D0=B0=D0=BD=D0=B4=D1=80?= Date: Sat, 4 Mar 2023 00:18:38 +0300 Subject: [PATCH 08/58] Edit method --- .../rar/game/repository/WikiGameDumbImpl.kt | 2 +- .../wiki/remote/WikiRemoteDataSourceImpl.kt | 46 +++++++++---------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt b/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt index ffc6c6d..d98dfc0 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt +++ b/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt @@ -76,7 +76,7 @@ class WikiGameDumbImpl : WikiGame { return } - println("Started for ${page.title}, depth = $curDepth") +// println("Started for ${page.title}, depth = $curDepth") val links = wikiRemoteDataSource.getLinksByTitle(page.title) visitedPages[page.title] = RESPONSE_RECEIVED diff --git a/wiki-game-coroutines/src/main/java/point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt b/wiki-game-coroutines/src/main/java/point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt index 596426e..db7f80c 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt +++ b/wiki-game-coroutines/src/main/java/point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt @@ -14,7 +14,10 @@ import kotlinx.serialization.json.Json import point.rar.wiki.data.source.WikiRemoteDataSource import point.rar.wiki.domain.model.WikiBacklinksResponse import point.rar.wiki.domain.model.WikiLinksResponse +import java.security.cert.X509Certificate import java.time.Duration +import javax.net.ssl.SSLContext +import javax.net.ssl.X509TrustManager class WikiRemoteDataSourceImpl : WikiRemoteDataSource { companion object Parameter { @@ -24,7 +27,7 @@ class WikiRemoteDataSourceImpl : WikiRemoteDataSource { private val rateLimiterConfig = RateLimiterConfig .custom() .limitForPeriod(1) - .limitRefreshPeriod(Duration.ofMillis(5)) + .limitRefreshPeriod(Duration.ofMillis(6)) .timeoutDuration(Duration.ofDays(10000)) .build() @@ -36,32 +39,11 @@ class WikiRemoteDataSourceImpl : WikiRemoteDataSource { json(Json { ignoreUnknownKeys = true }) - } - } - - override suspend fun getLinksByTitle(title: String): List { - return _getLinksByTitle(title) - } - override suspend fun getBacklinksByTitle(title: String): List { - val request = client.get(URL) { - parameter("action", "query") - parameter("bltitle", title) - parameter("list", "backlinks") - parameter("bllimit", "max") - parameter("format", "json") - parameter("blnamespace", 0) } - - val wikiBacklinksResponse: WikiBacklinksResponse = request.body() - - return wikiBacklinksResponse - .query - .backlinks - .map { it.title } } - private suspend fun _getLinksByTitle(title: String): List { + override suspend fun getLinksByTitle(title: String): List { val response = rateLimiter.executeSuspendFunction { client.get(URL) { parameter("action", "query") @@ -85,4 +67,22 @@ class WikiRemoteDataSourceImpl : WikiRemoteDataSource { return links } + + override suspend fun getBacklinksByTitle(title: String): List { + val request = client.get(URL) { + parameter("action", "query") + parameter("bltitle", title) + parameter("list", "backlinks") + parameter("bllimit", "max") + parameter("format", "json") + parameter("blnamespace", 0) + } + + val wikiBacklinksResponse: WikiBacklinksResponse = request.body() + + return wikiBacklinksResponse + .query + .backlinks + .map { it.title } + } } \ No newline at end of file From e253b36a26d323a78d7ae87b06871b1656a5ed99 Mon Sep 17 00:00:00 2001 From: eqimd Date: Sat, 4 Mar 2023 00:21:17 +0300 Subject: [PATCH 09/58] Add context --- .../main/java/point/rar/game/repository/WikiGameDumbImpl.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt b/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt index d98dfc0..450b018 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt +++ b/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt @@ -27,7 +27,8 @@ class WikiGameDumbImpl : WikiGame { override fun play(startPageTitle: String, endPageTitle: String, maxDepth: Int): Result> = runBlocking { val visitedPages: MutableMap = ConcurrentHashMap() val resChannel = Channel>() - val scope = CoroutineScope(coroutineContext) + val ctx = newFixedThreadPoolContext(4, "fixed-thread-context") + val scope = CoroutineScope(ctx) val startPage = Page(startPageTitle, null) scope.launch { @@ -35,7 +36,7 @@ class WikiGameDumbImpl : WikiGame { } val resPage = resChannel.receive() - coroutineContext.cancelChildren() + ctx.cancelChildren() val endPage = resPage.getOrNull() ?: return@runBlocking Result.failure(resPage.exceptionOrNull()!!) val path = mutableListOf() From 08fb2d77b257a57444594fabad2692c05d9934db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A8=D0=B0=D1=85=D0=BE=D0=B2=20=D0=90=D0=BB=D0=B5=D0=BA?= =?UTF-8?q?=D1=81=D0=B0=D0=BD=D0=B4=D1=80?= Date: Sat, 4 Mar 2023 01:09:39 +0300 Subject: [PATCH 10/58] Edit method --- .../rar/game/repository/WikiGameDumbImpl.kt | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt b/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt index 450b018..d53561c 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt +++ b/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt @@ -41,15 +41,15 @@ class WikiGameDumbImpl : WikiGame { val endPage = resPage.getOrNull() ?: return@runBlocking Result.failure(resPage.exceptionOrNull()!!) val path = mutableListOf() - var curPg = endPage - while (curPg.parentPage != null) { - path.add(curPg.title) - curPg = curPg.parentPage!! - } - path.add(startPage.title) + var curPg: Page? = endPage + do { + path.add(curPg!!.title) + curPg = curPg!!.parentPage + } while (curPg != null) val pagesWithResponseCount = visitedPages.entries.filter { it.value == RESPONSE_RECEIVED }.count() println("Received responses from $pagesWithResponseCount pages") + return@runBlocking Result.success(path.reversed()) } @@ -85,7 +85,15 @@ class WikiGameDumbImpl : WikiGame { links.forEach { // Creates new scope because we don't want to wait for all the coroutines to complete coroutineScope.launch { - processPage(Page(it, page), endPageTitle, curDepth + 1, maxDepth, visitedPages, resChannel, coroutineScope) + processPage( + Page(it, page), + endPageTitle, + curDepth + 1, + maxDepth, + visitedPages, + resChannel, + coroutineScope + ) } } From 486e858002bff5a4b8ea1d7402253804511066f0 Mon Sep 17 00:00:00 2001 From: Aleksandr Shakhov Date: Tue, 20 Jun 2023 23:29:55 +0300 Subject: [PATCH 11/58] Create REEDME.md --- REEDME.md | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 REEDME.md diff --git a/REEDME.md b/REEDME.md new file mode 100644 index 0000000..75769a3 --- /dev/null +++ b/REEDME.md @@ -0,0 +1,48 @@ +Тезисы доклада: + +1. Вступление + - Важность многопоточности в разработке Java-приложений + - Цель доклада: исследовать различные реализации многопоточности на примере игры WikiGame + +2. Обзор WikiGame + - Описание игры WikiGame и ее механики + - Задачи игрока и требования к реализации + +3. Преимущества и сложности многопоточности + - Обзор преимуществ параллельного программирования + - Вызовы и сложности, связанные с многопоточностью + +4. Реализация с использованием класса Thread + - Объяснение создания и запуска потоков с помощью класса Thread + - Демонстрация синхронизации потоков для безопасной работы с общими данными в WikiGame + - Примеры использования методов wait() и notify() + +5. Реализация с использованием Executor и ExecutorService + - Введение в Executor Framework и его преимущества + - Использование ExecutorService для управления пулом потоков в WikiGame + - Показ примеров использования ExecutorService для выполнения задач в фоновом режиме + +6. Реализация с использованием CompletableFuture + - Обзор возможностей CompletableFuture для асинхронного программирования + - Примеры использования CompletableFuture для параллельной обработки задач в WikiGame + - Обработка исключений и синхронизация результатов с использованием CompletableFuture + +7. Реализация с использованием Coroutines + - Введение в понятие Coroutines и их роль в асинхронном программировании + - Примеры использования Coroutines для реализации параллельных задач в WikiGame + - Преимущества и особенности использования Coroutines в контексте многопоточности + +8. Сравнение и анализ реализаций + - Сравнение производительности и простоты использования каждой реализации в WikiGame + - Обсуждение ограничений, преимуществ и недостатков каждого подхода + - Рекомендации по выбору наиболее подходящей реализации в зависимости от конкретных требований + +9. Заключение + - Подведение итогов и обобщение основных результатов доклада + - Значимость многопоточности в современном развитии Java-приложений + + +Fork/Join framework +Loom +RxJava +Actor Model From 75d3bd0938f13920f52b8e8ea35507ddacaea054 Mon Sep 17 00:00:00 2001 From: Aleksandr Shakhov Date: Tue, 20 Jun 2023 23:30:59 +0300 Subject: [PATCH 12/58] Rename REEDME.md to README.md --- REEDME.md => README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename REEDME.md => README.md (100%) diff --git a/REEDME.md b/README.md similarity index 100% rename from REEDME.md rename to README.md From 5398427c5fea5d46de9c6dee8c20dba66368ccd5 Mon Sep 17 00:00:00 2001 From: Daniil Lyubaev Date: Fri, 21 Jul 2023 14:52:33 +0300 Subject: [PATCH 13/58] Some fixes --- wiki-game-coroutines/.gitignore | 2 + .../rar/game/repository/WikiGameDumbImpl.kt | 54 ++++++++++--------- 2 files changed, 30 insertions(+), 26 deletions(-) create mode 100644 wiki-game-coroutines/.gitignore diff --git a/wiki-game-coroutines/.gitignore b/wiki-game-coroutines/.gitignore new file mode 100644 index 0000000..5b2e2bb --- /dev/null +++ b/wiki-game-coroutines/.gitignore @@ -0,0 +1,2 @@ +.gradle* +build* \ No newline at end of file diff --git a/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt b/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt index d53561c..06e2fab 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt +++ b/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt @@ -1,18 +1,15 @@ package point.rar.game.repository -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.CoroutineStart -import kotlinx.coroutines.cancel -import kotlinx.coroutines.cancelChildren +import kotlinx.coroutines.* import kotlinx.coroutines.channels.Channel -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.launch -import kotlinx.coroutines.newFixedThreadPoolContext -import kotlinx.coroutines.runBlocking -import kotlinx.coroutines.withContext +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.flow.flowOf import point.rar.wiki.data.source.WikiRemoteDataSource import point.rar.wiki.domain.model.Page import point.rar.wiki.remote.WikiRemoteDataSourceImpl +import java.lang.RuntimeException import java.util.concurrent.ConcurrentHashMap import kotlin.coroutines.coroutineContext @@ -26,28 +23,25 @@ class WikiGameDumbImpl : WikiGame { override fun play(startPageTitle: String, endPageTitle: String, maxDepth: Int): Result> = runBlocking { val visitedPages: MutableMap = ConcurrentHashMap() - val resChannel = Channel>() val ctx = newFixedThreadPoolContext(4, "fixed-thread-context") val scope = CoroutineScope(ctx) val startPage = Page(startPageTitle, null) - scope.launch { - processPage(startPage, endPageTitle, 0, maxDepth, visitedPages, resChannel, scope) - } - val resPage = resChannel.receive() + val res = processPage(startPage, endPageTitle, 0, maxDepth, visitedPages, scope) + ctx.cancelChildren() - val endPage = resPage.getOrNull() ?: return@runBlocking Result.failure(resPage.exceptionOrNull()!!) + val endPage = res.getOrNull() ?: return@runBlocking Result.failure(res.exceptionOrNull()!!) val path = mutableListOf() var curPg: Page? = endPage do { path.add(curPg!!.title) - curPg = curPg!!.parentPage + curPg = curPg.parentPage } while (curPg != null) - val pagesWithResponseCount = visitedPages.entries.filter { it.value == RESPONSE_RECEIVED }.count() + val pagesWithResponseCount = visitedPages.entries.count { it.value == RESPONSE_RECEIVED } println("Received responses from $pagesWithResponseCount pages") return@runBlocking Result.success(path.reversed()) @@ -59,22 +53,19 @@ class WikiGameDumbImpl : WikiGame { curDepth: Int, maxDepth: Int, visitedPages: MutableMap, - resChannel: Channel>, coroutineScope: CoroutineScope - ) { + ): Result { if (visitedPages.contains(page.title)) { - return + return Result.success(page) } visitedPages[page.title] = REQUEST_SENT if (page.title == endPageTitle) { - resChannel.send(Result.success(page)) - return + return Result.success(page) } if (curDepth == maxDepth) { - resChannel.send(Result.failure(RuntimeException("Depth is reached"))) - return + return Result.failure(RuntimeException("Depth reached")) } // println("Started for ${page.title}, depth = $curDepth") @@ -82,20 +73,31 @@ class WikiGameDumbImpl : WikiGame { visitedPages[page.title] = RESPONSE_RECEIVED + val ch = Channel>() + links.forEach { // Creates new scope because we don't want to wait for all the coroutines to complete coroutineScope.launch { - processPage( + val coroRes = processPage( Page(it, page), endPageTitle, curDepth + 1, maxDepth, visitedPages, - resChannel, coroutineScope ) + + ch.send(coroRes) + } + } + + for (i in 1..links.size) { + val chRes = ch.receive() + if (chRes.isSuccess) { + return chRes } } + return Result.failure(RuntimeException("Depth reached")) } } \ No newline at end of file From ace722ac7e7e871f18b34940fbe3b373e27e5526 Mon Sep 17 00:00:00 2001 From: Daniil Lyubaev Date: Fri, 21 Jul 2023 20:06:57 +0300 Subject: [PATCH 14/58] time --- .gitignore | 2 ++ wiki-game-coroutines/src/main/java/point/rar/Main.kt | 3 ++- .../java/point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt | 3 --- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index a1c2a23..c01f7ed 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,5 @@ # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* + +.idea* diff --git a/wiki-game-coroutines/src/main/java/point/rar/Main.kt b/wiki-game-coroutines/src/main/java/point/rar/Main.kt index 1f29124..a93d1ef 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/Main.kt +++ b/wiki-game-coroutines/src/main/java/point/rar/Main.kt @@ -8,6 +8,7 @@ fun main(args: Array) { val start = System.nanoTime() val path = wikiGame.play("Бакуган", "Библия", maxDepth = 6) - println((System.nanoTime() - start) / 1_000_000) + val timeSec = (System.nanoTime() - start) / (1_000_000_000f) + println("$timeSec s.") println(path) } \ No newline at end of file diff --git a/wiki-game-coroutines/src/main/java/point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt b/wiki-game-coroutines/src/main/java/point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt index db7f80c..1cbaa8b 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt +++ b/wiki-game-coroutines/src/main/java/point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt @@ -14,10 +14,7 @@ import kotlinx.serialization.json.Json import point.rar.wiki.data.source.WikiRemoteDataSource import point.rar.wiki.domain.model.WikiBacklinksResponse import point.rar.wiki.domain.model.WikiLinksResponse -import java.security.cert.X509Certificate import java.time.Duration -import javax.net.ssl.SSLContext -import javax.net.ssl.X509TrustManager class WikiRemoteDataSourceImpl : WikiRemoteDataSource { companion object Parameter { From 38b250bcc24b3b72efe1140aaa1e8aef8f568602 Mon Sep 17 00:00:00 2001 From: Daniil Lyubaev Date: Fri, 21 Jul 2023 20:41:37 +0300 Subject: [PATCH 15/58] fix --- .../src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt | 2 +- .../main/java/point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt b/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt index 06e2fab..7273b74 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt +++ b/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt @@ -56,7 +56,7 @@ class WikiGameDumbImpl : WikiGame { coroutineScope: CoroutineScope ): Result { if (visitedPages.contains(page.title)) { - return Result.success(page) + return Result.failure(RuntimeException("Exists")) } visitedPages[page.title] = REQUEST_SENT diff --git a/wiki-game-coroutines/src/main/java/point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt b/wiki-game-coroutines/src/main/java/point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt index 1cbaa8b..42eaba7 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt +++ b/wiki-game-coroutines/src/main/java/point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt @@ -24,7 +24,7 @@ class WikiRemoteDataSourceImpl : WikiRemoteDataSource { private val rateLimiterConfig = RateLimiterConfig .custom() .limitForPeriod(1) - .limitRefreshPeriod(Duration.ofMillis(6)) + .limitRefreshPeriod(Duration.ofMillis(40)) .timeoutDuration(Duration.ofDays(10000)) .build() From 026162b2123efcfc7f8e0b2c6ef902db054df72a Mon Sep 17 00:00:00 2001 From: Aleksandr Shakhov Date: Tue, 20 Jun 2023 23:29:55 +0300 Subject: [PATCH 16/58] Create REEDME.md --- REEDME.md | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 REEDME.md diff --git a/REEDME.md b/REEDME.md new file mode 100644 index 0000000..75769a3 --- /dev/null +++ b/REEDME.md @@ -0,0 +1,48 @@ +Тезисы доклада: + +1. Вступление + - Важность многопоточности в разработке Java-приложений + - Цель доклада: исследовать различные реализации многопоточности на примере игры WikiGame + +2. Обзор WikiGame + - Описание игры WikiGame и ее механики + - Задачи игрока и требования к реализации + +3. Преимущества и сложности многопоточности + - Обзор преимуществ параллельного программирования + - Вызовы и сложности, связанные с многопоточностью + +4. Реализация с использованием класса Thread + - Объяснение создания и запуска потоков с помощью класса Thread + - Демонстрация синхронизации потоков для безопасной работы с общими данными в WikiGame + - Примеры использования методов wait() и notify() + +5. Реализация с использованием Executor и ExecutorService + - Введение в Executor Framework и его преимущества + - Использование ExecutorService для управления пулом потоков в WikiGame + - Показ примеров использования ExecutorService для выполнения задач в фоновом режиме + +6. Реализация с использованием CompletableFuture + - Обзор возможностей CompletableFuture для асинхронного программирования + - Примеры использования CompletableFuture для параллельной обработки задач в WikiGame + - Обработка исключений и синхронизация результатов с использованием CompletableFuture + +7. Реализация с использованием Coroutines + - Введение в понятие Coroutines и их роль в асинхронном программировании + - Примеры использования Coroutines для реализации параллельных задач в WikiGame + - Преимущества и особенности использования Coroutines в контексте многопоточности + +8. Сравнение и анализ реализаций + - Сравнение производительности и простоты использования каждой реализации в WikiGame + - Обсуждение ограничений, преимуществ и недостатков каждого подхода + - Рекомендации по выбору наиболее подходящей реализации в зависимости от конкретных требований + +9. Заключение + - Подведение итогов и обобщение основных результатов доклада + - Значимость многопоточности в современном развитии Java-приложений + + +Fork/Join framework +Loom +RxJava +Actor Model From 0d70b6c4a0a57dc1ad03ebf79653c92ac6f50503 Mon Sep 17 00:00:00 2001 From: Aleksandr Shakhov Date: Tue, 20 Jun 2023 23:30:59 +0300 Subject: [PATCH 17/58] Rename REEDME.md to README.md --- REEDME.md => README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename REEDME.md => README.md (100%) diff --git a/REEDME.md b/README.md similarity index 100% rename from REEDME.md rename to README.md From 25bc93438285ad4b0beeb64fac08be18cc213d2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A8=D0=B0=D1=85=D0=BE=D0=B2=20=D0=90=D0=BB=D0=B5=D0=BA?= =?UTF-8?q?=D1=81=D0=B0=D0=BD=D0=B4=D1=80?= Date: Fri, 21 Jul 2023 04:00:59 +0300 Subject: [PATCH 18/58] CompletableFuture --- wiki-game-common/pom.xml | 19 ++++ .../wiki-game-completable-feature/pom.xml | 94 ++++++++++++++++ .../src/main/java/point/rar/Main.java | 12 +++ .../src/main/java/point/rar/WikiGame.kt | 5 + .../java/point/rar/WikiGameFutureImpl.java | 102 ++++++++++++++++++ .../java/point/rar/WikiGameSerialImpl.java | 89 +++++++++++++++ wiki-game-coroutines/build.gradle.kts | 1 + .../java/point/rar/wiki/domain/model/Link.kt | 2 +- .../point/rar/wiki/domain/model/PageLinks.kt | 2 +- .../point/rar/wiki/domain/model/QueryLinks.kt | 2 +- .../wiki/domain/model/WikiLinksResponse.kt | 2 +- 11 files changed, 326 insertions(+), 4 deletions(-) create mode 100644 wiki-game-common/wiki-game-completable-feature/pom.xml create mode 100644 wiki-game-common/wiki-game-completable-feature/src/main/java/point/rar/Main.java create mode 100644 wiki-game-common/wiki-game-completable-feature/src/main/java/point/rar/WikiGame.kt create mode 100644 wiki-game-common/wiki-game-completable-feature/src/main/java/point/rar/WikiGameFutureImpl.java create mode 100644 wiki-game-common/wiki-game-completable-feature/src/main/java/point/rar/WikiGameSerialImpl.java diff --git a/wiki-game-common/pom.xml b/wiki-game-common/pom.xml index 845f08c..e339e71 100644 --- a/wiki-game-common/pom.xml +++ b/wiki-game-common/pom.xml @@ -7,6 +7,10 @@ point.rar wiki-game-common 1.0-SNAPSHOT + pom + + wiki-game-completable-feature + 19 19 @@ -18,6 +22,21 @@ async-http-client 3.0.0.Beta1 + + io.github.resilience4j + resilience4j-ratelimiter + 2.1.0 + + + com.fasterxml.jackson.core + jackson-core + 2.15.2 + + + org.jetbrains.kotlinx + kotlinx-serialization-core-jvm + 1.2.2 + \ No newline at end of file diff --git a/wiki-game-common/wiki-game-completable-feature/pom.xml b/wiki-game-common/wiki-game-completable-feature/pom.xml new file mode 100644 index 0000000..7fa1509 --- /dev/null +++ b/wiki-game-common/wiki-game-completable-feature/pom.xml @@ -0,0 +1,94 @@ + + + 4.0.0 + + point.rar + wiki-game-common + 1.0-SNAPSHOT + + + wiki-game-completable-feature + + + 17 + 17 + UTF-8 + 1.9.0 + + + + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-test + ${kotlin.version} + test + + + point.rar + wiki-game-completable-feature + 1.0-SNAPSHOT + + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + 2.14.2 + + + + + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + compile + compile + + compile + + + + test-compile + test-compile + + test-compile + + + + + ${maven.compiler.target} + + + + org.apache.maven.plugins + maven-compiler-plugin + + + compile + compile + + compile + + + + testCompile + test-compile + + testCompile + + + + + + + + \ No newline at end of file diff --git a/wiki-game-common/wiki-game-completable-feature/src/main/java/point/rar/Main.java b/wiki-game-common/wiki-game-completable-feature/src/main/java/point/rar/Main.java new file mode 100644 index 0000000..efef9ce --- /dev/null +++ b/wiki-game-common/wiki-game-completable-feature/src/main/java/point/rar/Main.java @@ -0,0 +1,12 @@ +package point.rar; + +public class Main { + public static void main(String[] args) { + long startTime = System.currentTimeMillis(); + WikiGame wikiGame = new WikiGameFutureImpl(); + var path = wikiGame.play("Бакуган", "Библия", 6); + System.out.printf(path.toString()); + long endTime = System.currentTimeMillis(); + System.out.println("Total execution time: " + (endTime - startTime) + "ms"); + } +} \ No newline at end of file diff --git a/wiki-game-common/wiki-game-completable-feature/src/main/java/point/rar/WikiGame.kt b/wiki-game-common/wiki-game-completable-feature/src/main/java/point/rar/WikiGame.kt new file mode 100644 index 0000000..664e689 --- /dev/null +++ b/wiki-game-common/wiki-game-completable-feature/src/main/java/point/rar/WikiGame.kt @@ -0,0 +1,5 @@ +package point.rar + +interface WikiGame { + fun play(startPageTitle: String, endPageTitle: String, maxDepth: Int = 11): List +} \ No newline at end of file diff --git a/wiki-game-common/wiki-game-completable-feature/src/main/java/point/rar/WikiGameFutureImpl.java b/wiki-game-common/wiki-game-completable-feature/src/main/java/point/rar/WikiGameFutureImpl.java new file mode 100644 index 0000000..e6b1cd3 --- /dev/null +++ b/wiki-game-common/wiki-game-completable-feature/src/main/java/point/rar/WikiGameFutureImpl.java @@ -0,0 +1,102 @@ +package point.rar; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.jetbrains.annotations.NotNull; +import point.rar.wiki.domain.model.Link; +import point.rar.wiki.domain.model.Page; +import point.rar.wiki.domain.model.WikiLinksResponse; + +import java.io.IOException; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.util.*; +import java.util.concurrent.*; + +public class WikiGameFutureImpl implements WikiGame { + private static final String URL = "https://ru.wikipedia.org/w/api.php"; + + @NotNull + @Override + public List play(String startPageTitle, String endPageTitle, int maxDepth) { + var startedPage = new Page(startPageTitle, null); + Queue rawPages = new ConcurrentLinkedQueue<>(Collections.singleton(startedPage)); + Queue parsedPages = new ConcurrentLinkedQueue<>(); + Set parsedTitle = new ConcurrentSkipListSet<>(); + var parentEndPage = startedPage; + + ExecutorService executorService = Executors.newCachedThreadPool(); + List> futures = new ArrayList<>(); + + do { + for (int i = 0; i < 50; i++) { + Page curPage = rawPages.poll(); + if (curPage == null) { + break; + } + CompletableFuture future = CompletableFuture.runAsync(() -> makeSearch(curPage, rawPages, parsedPages, parsedTitle), executorService); + futures.add(future); + } + CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join(); + futures.clear(); + } while (!parsedTitle.contains(endPageTitle)); + parsedPages.add(new Page(endPageTitle, parentEndPage)); + + executorService.shutdown(); + return getResultPath(parsedPages, endPageTitle); + } + + private void makeSearch(Page curPage, Queue rawPages, Queue parsedPages, Set parsedTitle) { + List newLinks = getChildLinks(curPage.getTitle()); + parsedPages.add(curPage); + parsedTitle.addAll(newLinks); + rawPages.addAll(newLinks.stream() + .map(m -> new Page(m, curPage)) + .toList()); + } + + private List getResultPath(Queue parsedPages, String endPageTitle) { + var path = new ArrayList(); + var curPage = parsedPages.stream() + .filter(p -> p.getTitle().equals(endPageTitle)) + .findAny() + .orElseThrow(); + while (curPage.getParentPage() != null) { + path.add(curPage.getTitle()); + curPage = curPage.getParentPage(); + } + path.add(curPage.getTitle()); + Collections.reverse(path); // Reverse the order of elements in the list + return path; + } + + + private List getChildLinks(String title) { + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + try { + System.out.println("Get links for: " + title); + String responseBody = HttpClient.newBuilder() + .build() + .send(HttpRequest.newBuilder() + .uri(URI.create(URL + "?action=query&prop=links&pllimit=max&format=json&plnamespace=0&titles=" + title.replace(" ", "%20"))) + .GET() + .build(), HttpResponse.BodyHandlers.ofString()).body(); + WikiLinksResponse response = objectMapper.readValue(responseBody, WikiLinksResponse.class); + + return parseLinks(response); + } catch (IOException | InterruptedException e) { + throw new RuntimeException(e); + } + } + + @NotNull + private static List parseLinks(WikiLinksResponse response) { + return response.getQuery().getPages().entrySet().iterator().next().getValue().getLinks() + .stream() + .map(Link::getTitle) + .toList(); + } +} diff --git a/wiki-game-common/wiki-game-completable-feature/src/main/java/point/rar/WikiGameSerialImpl.java b/wiki-game-common/wiki-game-completable-feature/src/main/java/point/rar/WikiGameSerialImpl.java new file mode 100644 index 0000000..b09c00e --- /dev/null +++ b/wiki-game-common/wiki-game-completable-feature/src/main/java/point/rar/WikiGameSerialImpl.java @@ -0,0 +1,89 @@ +package point.rar; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.jetbrains.annotations.NotNull; +import point.rar.wiki.domain.model.Link; +import point.rar.wiki.domain.model.Page; +import point.rar.wiki.domain.model.WikiLinksResponse; + +import java.io.IOException; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.util.*; + +public class WikiGameSerialImpl implements WikiGame { + private static final String URL = "https://ru.wikipedia.org/w/api.php"; + + @NotNull + @Override + public List play(String startPageTitle, String endPageTitle, int maxDepth) { + var startedPage = new Page(startPageTitle, null); + Queue rawPages = new LinkedList<>(Collections.singleton(startedPage)); + Queue parsedPages = new LinkedList<>(); + Set parsedTitle = new HashSet<>(); + var parentEndPage = startedPage; + do { + System.out.println("parsedPages size = " + parsedPages.size()); + System.out.println("rawPages size = " + rawPages.size()); + System.out.println("parsedTitle size = " + parsedTitle.size()); + var curPage = rawPages.poll(); + parentEndPage = curPage; + var newLinks = parseLinks(curPage.getTitle()); + parsedPages.add(curPage); + parsedTitle.addAll(newLinks); + rawPages.addAll( + newLinks.stream() + .map(m -> new Page(m, curPage)) + .toList() + ); + } while (!parsedTitle.contains(endPageTitle)); + parsedPages.add(new Page(endPageTitle, parentEndPage)); + + return getResultPath(parsedPages, endPageTitle); + } + + private List getResultPath(Queue parsedPages, String endPageTitle) { + var path = new ArrayList(); + var curPage = parsedPages.stream() + .filter(p -> p.getTitle().equals(endPageTitle)) + .findAny() + .orElseThrow(); + while (curPage.getParentPage() != null) { + path.add(curPage.getTitle()); + curPage = curPage.getParentPage(); + } + path.add(curPage.getTitle()); + return path; + } + + + private List parseLinks(String title) { + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + try { + System.out.println("Get links for: " + title); + String responseBody = HttpClient.newBuilder() + .build() + .send(HttpRequest.newBuilder() + .uri(URI.create(URL + "?action=query&prop=links&pllimit=max&format=json&plnamespace=0&titles=" + title.replace(" ", "%20"))) + .GET() + .build(), HttpResponse.BodyHandlers.ofString()).body(); + WikiLinksResponse response = objectMapper.readValue(responseBody, WikiLinksResponse.class); + + return parseLinks(response); + } catch (IOException | InterruptedException e) { + throw new RuntimeException(e); + } + } + + @NotNull + private static List parseLinks(WikiLinksResponse response) { + return response.getQuery().getPages().entrySet().iterator().next().getValue().getLinks() + .stream() + .map(Link::getTitle) + .toList(); + } +} diff --git a/wiki-game-coroutines/build.gradle.kts b/wiki-game-coroutines/build.gradle.kts index 2c84f20..b76cee9 100644 --- a/wiki-game-coroutines/build.gradle.kts +++ b/wiki-game-coroutines/build.gradle.kts @@ -14,6 +14,7 @@ repositories { } dependencies { + implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.14.2") testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.1") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.1") implementation(kotlin("stdlib-jdk8")) diff --git a/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/Link.kt b/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/Link.kt index 8adc63a..6329a20 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/Link.kt +++ b/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/Link.kt @@ -4,5 +4,5 @@ import kotlinx.serialization.Serializable @Serializable data class Link( - val title: String, + val title: String = "" ) diff --git a/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/PageLinks.kt b/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/PageLinks.kt index 92f3826..56616f2 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/PageLinks.kt +++ b/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/PageLinks.kt @@ -4,5 +4,5 @@ import kotlinx.serialization.Serializable @Serializable data class PageLinks( - val links: List? = null + val links: List? = emptyList() ) diff --git a/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/QueryLinks.kt b/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/QueryLinks.kt index bbc0dd0..50064cc 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/QueryLinks.kt +++ b/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/QueryLinks.kt @@ -4,5 +4,5 @@ import kotlinx.serialization.Serializable @Serializable data class QueryLinks( - val pages: Map + val pages: Map = emptyMap() ) diff --git a/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/WikiLinksResponse.kt b/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/WikiLinksResponse.kt index a3cc428..eff9443 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/WikiLinksResponse.kt +++ b/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/WikiLinksResponse.kt @@ -4,5 +4,5 @@ import kotlinx.serialization.Serializable @Serializable data class WikiLinksResponse( - val query: QueryLinks + val query: QueryLinks = QueryLinks(emptyMap()) ) \ No newline at end of file From c740dbcb2a691bf62dcbd8ac08d3536271aba801 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A8=D0=B0=D1=85=D0=BE=D0=B2=20=D0=90=D0=BB=D0=B5=D0=BA?= =?UTF-8?q?=D1=81=D0=B0=D0=BD=D0=B4=D1=80?= Date: Fri, 21 Jul 2023 04:08:13 +0300 Subject: [PATCH 19/58] Fix getResultPath --- .../main/java/point/rar/WikiGameFutureImpl.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/wiki-game-common/wiki-game-completable-feature/src/main/java/point/rar/WikiGameFutureImpl.java b/wiki-game-common/wiki-game-completable-feature/src/main/java/point/rar/WikiGameFutureImpl.java index e6b1cd3..ee5ba6d 100644 --- a/wiki-game-common/wiki-game-completable-feature/src/main/java/point/rar/WikiGameFutureImpl.java +++ b/wiki-game-common/wiki-game-completable-feature/src/main/java/point/rar/WikiGameFutureImpl.java @@ -25,13 +25,12 @@ public List play(String startPageTitle, String endPageTitle, int maxDept Queue rawPages = new ConcurrentLinkedQueue<>(Collections.singleton(startedPage)); Queue parsedPages = new ConcurrentLinkedQueue<>(); Set parsedTitle = new ConcurrentSkipListSet<>(); - var parentEndPage = startedPage; ExecutorService executorService = Executors.newCachedThreadPool(); List> futures = new ArrayList<>(); do { - for (int i = 0; i < 50; i++) { + for (int i = 0; i < 100; i++) { Page curPage = rawPages.poll(); if (curPage == null) { break; @@ -42,7 +41,14 @@ public List play(String startPageTitle, String endPageTitle, int maxDept CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join(); futures.clear(); } while (!parsedTitle.contains(endPageTitle)); - parsedPages.add(new Page(endPageTitle, parentEndPage)); + parsedPages.add( + new Page(endPageTitle, + rawPages.stream() + .filter(p -> p.getTitle().equals(endPageTitle)) + .findAny() + .orElseThrow() + ) + ); executorService.shutdown(); return getResultPath(parsedPages, endPageTitle); @@ -64,10 +70,9 @@ private List getResultPath(Queue parsedPages, String endPageTitle) .findAny() .orElseThrow(); while (curPage.getParentPage() != null) { - path.add(curPage.getTitle()); curPage = curPage.getParentPage(); + path.add(curPage.getTitle()); } - path.add(curPage.getTitle()); Collections.reverse(path); // Reverse the order of elements in the list return path; } From d12648f05653af71c89b53f0c6f3f22791d3c777 Mon Sep 17 00:00:00 2001 From: Daniil Lyubaev Date: Fri, 21 Jul 2023 20:59:04 +0300 Subject: [PATCH 20/58] fixes --- .../src/main/java/point/rar/game/repository/WikiGame.kt | 2 +- .../main/java/point/rar/game/repository/WikiGameDumbImpl.kt | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGame.kt b/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGame.kt index 0f60b09..4957811 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGame.kt +++ b/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGame.kt @@ -1,5 +1,5 @@ package point.rar.game.repository interface WikiGame { - fun play(startPageTitle: String, endPageTitle: String, maxDepth: Int = 11): Result> + fun play(startPageTitle: String, endPageTitle: String, maxDepth: Int = 11): List } \ No newline at end of file diff --git a/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt b/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt index 7273b74..abe8ad4 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt +++ b/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt @@ -21,7 +21,7 @@ class WikiGameDumbImpl : WikiGame { private val wikiRemoteDataSource: WikiRemoteDataSource = WikiRemoteDataSourceImpl() - override fun play(startPageTitle: String, endPageTitle: String, maxDepth: Int): Result> = runBlocking { + override fun play(startPageTitle: String, endPageTitle: String, maxDepth: Int): List = runBlocking { val visitedPages: MutableMap = ConcurrentHashMap() val ctx = newFixedThreadPoolContext(4, "fixed-thread-context") val scope = CoroutineScope(ctx) @@ -32,7 +32,7 @@ class WikiGameDumbImpl : WikiGame { ctx.cancelChildren() - val endPage = res.getOrNull() ?: return@runBlocking Result.failure(res.exceptionOrNull()!!) + val endPage = res.getOrNull() ?: throw res.exceptionOrNull()!! val path = mutableListOf() var curPg: Page? = endPage @@ -44,7 +44,7 @@ class WikiGameDumbImpl : WikiGame { val pagesWithResponseCount = visitedPages.entries.count { it.value == RESPONSE_RECEIVED } println("Received responses from $pagesWithResponseCount pages") - return@runBlocking Result.success(path.reversed()) + return@runBlocking path.reversed() } private suspend fun processPage( From 548eb5a777b699d0b6614efb3b4d4f9f2c580427 Mon Sep 17 00:00:00 2001 From: Daniil Lyubaev Date: Fri, 21 Jul 2023 21:03:50 +0300 Subject: [PATCH 21/58] some more --- .../rar/game/repository/WikiGameDumbImpl.kt | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt b/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt index abe8ad4..3a4654d 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt +++ b/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt @@ -2,16 +2,12 @@ package point.rar.game.repository import kotlinx.coroutines.* import kotlinx.coroutines.channels.Channel -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.coroutines.flow.flow -import kotlinx.coroutines.flow.flowOf import point.rar.wiki.data.source.WikiRemoteDataSource import point.rar.wiki.domain.model.Page import point.rar.wiki.remote.WikiRemoteDataSourceImpl import java.lang.RuntimeException +import java.util.Optional import java.util.concurrent.ConcurrentHashMap -import kotlin.coroutines.coroutineContext class WikiGameDumbImpl : WikiGame { companion object { @@ -29,10 +25,13 @@ class WikiGameDumbImpl : WikiGame { val startPage = Page(startPageTitle, null) val res = processPage(startPage, endPageTitle, 0, maxDepth, visitedPages, scope) + if (res.isEmpty) { + throw RuntimeException("Depth reached") + } ctx.cancelChildren() - val endPage = res.getOrNull() ?: throw res.exceptionOrNull()!! + val endPage = res.get() val path = mutableListOf() var curPg: Page? = endPage @@ -54,18 +53,18 @@ class WikiGameDumbImpl : WikiGame { maxDepth: Int, visitedPages: MutableMap, coroutineScope: CoroutineScope - ): Result { + ): Optional { if (visitedPages.contains(page.title)) { - return Result.failure(RuntimeException("Exists")) + return Optional.empty() } visitedPages[page.title] = REQUEST_SENT if (page.title == endPageTitle) { - return Result.success(page) + return Optional.of(page) } if (curDepth == maxDepth) { - return Result.failure(RuntimeException("Depth reached")) + return Optional.empty() } // println("Started for ${page.title}, depth = $curDepth") @@ -73,7 +72,7 @@ class WikiGameDumbImpl : WikiGame { visitedPages[page.title] = RESPONSE_RECEIVED - val ch = Channel>() + val ch = Channel>() links.forEach { // Creates new scope because we don't want to wait for all the coroutines to complete @@ -93,11 +92,11 @@ class WikiGameDumbImpl : WikiGame { for (i in 1..links.size) { val chRes = ch.receive() - if (chRes.isSuccess) { + if (chRes.isPresent) { return chRes } } - return Result.failure(RuntimeException("Depth reached")) + return Optional.empty() } } \ No newline at end of file From 1890b3faa9f86bb6637fc815dba1635d8aecfd92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A8=D0=B0=D1=85=D0=BE=D0=B2=20=D0=90=D0=BB=D0=B5=D0=BA?= =?UTF-8?q?=D1=81=D0=B0=D0=BD=D0=B4=D1=80?= Date: Fri, 21 Jul 2023 21:56:57 +0300 Subject: [PATCH 22/58] Add Loom --- wiki-game-common/pom.xml | 3 --- .../pom.xml | 13 +++++++++-- .../src/main/java/point/rar/Main.java | 1 + .../src/main/java/point/rar/WikiGame.kt | 0 .../java/point/rar/WikiGameFutureImpl.java | 22 ++++++++++++++----- .../java/point/rar/WikiGameSerialImpl.java | 0 .../wiki/remote/WikiRemoteDataSourceImpl.kt | 2 +- 7 files changed, 30 insertions(+), 11 deletions(-) rename {wiki-game-common/wiki-game-completable-feature => wiki-game-completable-feature}/pom.xml (88%) rename {wiki-game-common/wiki-game-completable-feature => wiki-game-completable-feature}/src/main/java/point/rar/Main.java (86%) rename {wiki-game-common/wiki-game-completable-feature => wiki-game-completable-feature}/src/main/java/point/rar/WikiGame.kt (100%) rename {wiki-game-common/wiki-game-completable-feature => wiki-game-completable-feature}/src/main/java/point/rar/WikiGameFutureImpl.java (80%) rename {wiki-game-common/wiki-game-completable-feature => wiki-game-completable-feature}/src/main/java/point/rar/WikiGameSerialImpl.java (100%) diff --git a/wiki-game-common/pom.xml b/wiki-game-common/pom.xml index e339e71..24ffe60 100644 --- a/wiki-game-common/pom.xml +++ b/wiki-game-common/pom.xml @@ -8,9 +8,6 @@ wiki-game-common 1.0-SNAPSHOT pom - - wiki-game-completable-feature - 19 19 diff --git a/wiki-game-common/wiki-game-completable-feature/pom.xml b/wiki-game-completable-feature/pom.xml similarity index 88% rename from wiki-game-common/wiki-game-completable-feature/pom.xml rename to wiki-game-completable-feature/pom.xml index 7fa1509..0ddac0a 100644 --- a/wiki-game-common/wiki-game-completable-feature/pom.xml +++ b/wiki-game-completable-feature/pom.xml @@ -12,8 +12,8 @@ wiki-game-completable-feature - 17 - 17 + 20 + 20 UTF-8 1.9.0 @@ -40,6 +40,11 @@ jackson-dataformat-xml 2.14.2 + + org.apache.httpcomponents + httpclient + 4.5.1 + @@ -87,6 +92,10 @@ + + 19 + 19 + diff --git a/wiki-game-common/wiki-game-completable-feature/src/main/java/point/rar/Main.java b/wiki-game-completable-feature/src/main/java/point/rar/Main.java similarity index 86% rename from wiki-game-common/wiki-game-completable-feature/src/main/java/point/rar/Main.java rename to wiki-game-completable-feature/src/main/java/point/rar/Main.java index efef9ce..06a39e0 100644 --- a/wiki-game-common/wiki-game-completable-feature/src/main/java/point/rar/Main.java +++ b/wiki-game-completable-feature/src/main/java/point/rar/Main.java @@ -4,6 +4,7 @@ public class Main { public static void main(String[] args) { long startTime = System.currentTimeMillis(); WikiGame wikiGame = new WikiGameFutureImpl(); +// var path = wikiGame.play("Алгебра", "Ятаган", 6); var path = wikiGame.play("Бакуган", "Библия", 6); System.out.printf(path.toString()); long endTime = System.currentTimeMillis(); diff --git a/wiki-game-common/wiki-game-completable-feature/src/main/java/point/rar/WikiGame.kt b/wiki-game-completable-feature/src/main/java/point/rar/WikiGame.kt similarity index 100% rename from wiki-game-common/wiki-game-completable-feature/src/main/java/point/rar/WikiGame.kt rename to wiki-game-completable-feature/src/main/java/point/rar/WikiGame.kt diff --git a/wiki-game-common/wiki-game-completable-feature/src/main/java/point/rar/WikiGameFutureImpl.java b/wiki-game-completable-feature/src/main/java/point/rar/WikiGameFutureImpl.java similarity index 80% rename from wiki-game-common/wiki-game-completable-feature/src/main/java/point/rar/WikiGameFutureImpl.java rename to wiki-game-completable-feature/src/main/java/point/rar/WikiGameFutureImpl.java index ee5ba6d..56a903c 100644 --- a/wiki-game-common/wiki-game-completable-feature/src/main/java/point/rar/WikiGameFutureImpl.java +++ b/wiki-game-completable-feature/src/main/java/point/rar/WikiGameFutureImpl.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.http.client.utils.URIBuilder; import org.jetbrains.annotations.NotNull; import point.rar.wiki.domain.model.Link; import point.rar.wiki.domain.model.Page; @@ -9,6 +10,7 @@ import java.io.IOException; import java.net.URI; +import java.net.URISyntaxException; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; @@ -27,6 +29,8 @@ public List play(String startPageTitle, String endPageTitle, int maxDept Set parsedTitle = new ConcurrentSkipListSet<>(); ExecutorService executorService = Executors.newCachedThreadPool(); +// ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); +// ExecutorService executorService = Executors.newVirtualThreadPerTaskExecutor(); List> futures = new ArrayList<>(); do { @@ -81,18 +85,26 @@ private List getResultPath(Queue parsedPages, String endPageTitle) private List getChildLinks(String title) { ObjectMapper objectMapper = new ObjectMapper(); objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + try { - System.out.println("Get links for: " + title); + URIBuilder uriBuilder = new URIBuilder(URL); + uriBuilder.addParameter("action", "query"); + uriBuilder.addParameter("prop", "links"); + uriBuilder.addParameter("pllimit", "max"); + uriBuilder.addParameter("format", "json"); + uriBuilder.addParameter("plnamespace", "titles"); + +// System.out.println("Get links for: " + title); String responseBody = HttpClient.newBuilder() .build() - .send(HttpRequest.newBuilder() - .uri(URI.create(URL + "?action=query&prop=links&pllimit=max&format=json&plnamespace=0&titles=" + title.replace(" ", "%20"))) + .sendAsync(HttpRequest.newBuilder() + .uri(URI.create(uriBuilder.addParameter("titles", title).build().toString())) .GET() - .build(), HttpResponse.BodyHandlers.ofString()).body(); + .build(), HttpResponse.BodyHandlers.ofString()).get().body(); WikiLinksResponse response = objectMapper.readValue(responseBody, WikiLinksResponse.class); return parseLinks(response); - } catch (IOException | InterruptedException e) { + } catch (IOException | InterruptedException | URISyntaxException | ExecutionException e) { throw new RuntimeException(e); } } diff --git a/wiki-game-common/wiki-game-completable-feature/src/main/java/point/rar/WikiGameSerialImpl.java b/wiki-game-completable-feature/src/main/java/point/rar/WikiGameSerialImpl.java similarity index 100% rename from wiki-game-common/wiki-game-completable-feature/src/main/java/point/rar/WikiGameSerialImpl.java rename to wiki-game-completable-feature/src/main/java/point/rar/WikiGameSerialImpl.java diff --git a/wiki-game-coroutines/src/main/java/point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt b/wiki-game-coroutines/src/main/java/point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt index 42eaba7..227f955 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt +++ b/wiki-game-coroutines/src/main/java/point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt @@ -24,7 +24,7 @@ class WikiRemoteDataSourceImpl : WikiRemoteDataSource { private val rateLimiterConfig = RateLimiterConfig .custom() .limitForPeriod(1) - .limitRefreshPeriod(Duration.ofMillis(40)) + .limitRefreshPeriod(Duration.ofMillis(3)) .timeoutDuration(Duration.ofDays(10000)) .build() From 044df7d12770860c7d2fd08a60d7df86e118ff88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A8=D0=B0=D1=85=D0=BE=D0=B2=20=D0=90=D0=BB=D0=B5=D0=BA?= =?UTF-8?q?=D1=81=D0=B0=D0=BD=D0=B4=D1=80?= Date: Mon, 31 Jul 2023 22:06:12 +0300 Subject: [PATCH 23/58] Fix structure --- wiki-game-common/pom.xml | 70 ++++++++++++++++++- .../java/point/rar/adapter/WikiRequest.java | 4 -- .../java/point/rar/adapter/WikiResponse.java | 4 -- .../java/point/rar/{ => common}/Main.java | 2 +- .../rar/common}/wiki/domain/model/Link.kt | 2 +- .../rar/common}/wiki/domain/model/Page.kt | 2 +- .../common}/wiki/domain/model/PageLinks.kt | 2 +- .../wiki/domain/model/QueryBacklinks.kt | 2 +- .../common}/wiki/domain/model/QueryLinks.kt | 2 +- .../domain/model/WikiBacklinksResponse.kt | 2 +- .../wiki/domain/model/WikiLinksResponse.kt | 2 +- .../src/main/java/point/rar/domain/Page.java | 4 -- .../java/point/rar/domain/model/Link.java | 4 -- .../point/rar/domain/model/PageLinks.java | 6 -- .../rar/domain/model/QueryBacklinks.java | 7 -- .../point/rar/domain/model/QueryLinks.java | 8 --- .../domain/model/WikiBacklinksResponse.java | 4 -- .../rar/domain/model/WikiLinksResponse.java | 4 -- wiki-game-completable-feature/pom.xml | 22 +++--- .../java/point/rar/{ => feature}/Main.java | 2 +- .../java/point/rar/{ => feature}/WikiGame.kt | 2 +- .../rar/{ => feature}/WikiGameFutureImpl.java | 5 +- .../rar/{ => feature}/WikiGameSerialImpl.java | 5 +- .../java/point/rar/{ => coroutines}/Main.kt | 6 +- .../repository/WikiGame.kt | 2 +- .../repository/WikiGameDumbImpl.kt | 8 +-- .../wiki}/WikiRemoteDataSourceImpl.kt | 5 +- .../wiki/data/source/WikiRemoteDataSource.kt | 2 +- 28 files changed, 100 insertions(+), 90 deletions(-) delete mode 100644 wiki-game-common/src/main/java/point/rar/adapter/WikiRequest.java delete mode 100644 wiki-game-common/src/main/java/point/rar/adapter/WikiResponse.java rename wiki-game-common/src/main/java/point/rar/{ => common}/Main.java (81%) rename {wiki-game-coroutines/src/main/java/point/rar => wiki-game-common/src/main/java/point/rar/common}/wiki/domain/model/Link.kt (70%) rename {wiki-game-coroutines/src/main/java/point/rar => wiki-game-common/src/main/java/point/rar/common}/wiki/domain/model/Page.kt (57%) rename {wiki-game-coroutines/src/main/java/point/rar => wiki-game-common/src/main/java/point/rar/common}/wiki/domain/model/PageLinks.kt (74%) rename {wiki-game-coroutines/src/main/java/point/rar => wiki-game-common/src/main/java/point/rar/common}/wiki/domain/model/QueryBacklinks.kt (73%) rename {wiki-game-coroutines/src/main/java/point/rar => wiki-game-common/src/main/java/point/rar/common}/wiki/domain/model/QueryLinks.kt (75%) rename {wiki-game-coroutines/src/main/java/point/rar => wiki-game-common/src/main/java/point/rar/common}/wiki/domain/model/WikiBacklinksResponse.kt (74%) rename {wiki-game-coroutines/src/main/java/point/rar => wiki-game-common/src/main/java/point/rar/common}/wiki/domain/model/WikiLinksResponse.kt (76%) delete mode 100644 wiki-game-common/src/main/java/point/rar/domain/Page.java delete mode 100644 wiki-game-common/src/main/java/point/rar/domain/model/Link.java delete mode 100644 wiki-game-common/src/main/java/point/rar/domain/model/PageLinks.java delete mode 100644 wiki-game-common/src/main/java/point/rar/domain/model/QueryBacklinks.java delete mode 100644 wiki-game-common/src/main/java/point/rar/domain/model/QueryLinks.java delete mode 100644 wiki-game-common/src/main/java/point/rar/domain/model/WikiBacklinksResponse.java delete mode 100644 wiki-game-common/src/main/java/point/rar/domain/model/WikiLinksResponse.java rename wiki-game-completable-feature/src/main/java/point/rar/{ => feature}/Main.java (94%) rename wiki-game-completable-feature/src/main/java/point/rar/{ => feature}/WikiGame.kt (81%) rename wiki-game-completable-feature/src/main/java/point/rar/{ => feature}/WikiGameFutureImpl.java (96%) rename wiki-game-completable-feature/src/main/java/point/rar/{ => feature}/WikiGameSerialImpl.java (95%) rename wiki-game-coroutines/src/main/java/point/rar/{ => coroutines}/Main.kt (69%) rename wiki-game-coroutines/src/main/java/point/rar/{game => coroutines}/repository/WikiGame.kt (74%) rename wiki-game-coroutines/src/main/java/point/rar/{game => coroutines}/repository/WikiGameDumbImpl.kt (93%) rename wiki-game-coroutines/src/main/java/point/rar/{wiki/remote => coroutines/wiki}/WikiRemoteDataSourceImpl.kt (92%) rename wiki-game-coroutines/src/main/java/point/rar/{ => coroutines}/wiki/data/source/WikiRemoteDataSource.kt (77%) diff --git a/wiki-game-common/pom.xml b/wiki-game-common/pom.xml index 24ffe60..e5ac831 100644 --- a/wiki-game-common/pom.xml +++ b/wiki-game-common/pom.xml @@ -4,13 +4,14 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - point.rar + point.rar.common wiki-game-common 1.0-SNAPSHOT pom 19 19 + 1.9.0 @@ -36,4 +37,71 @@ + + + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + compile + process-sources + + compile + + + + test-compile + test-compile + + test-compile + + + + + ${maven.compiler.target} + + + + org.apache.maven.plugins + maven-compiler-plugin + + + compile + compile + + compile + + + + testCompile + test-compile + + testCompile + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-dependencies + prepare-package + + copy-dependencies + + + + ${project.build.directory}/libs + + + + + + + \ No newline at end of file diff --git a/wiki-game-common/src/main/java/point/rar/adapter/WikiRequest.java b/wiki-game-common/src/main/java/point/rar/adapter/WikiRequest.java deleted file mode 100644 index aa61c84..0000000 --- a/wiki-game-common/src/main/java/point/rar/adapter/WikiRequest.java +++ /dev/null @@ -1,4 +0,0 @@ -package point.rar.adapter; - -public record WikiRequest() { -} diff --git a/wiki-game-common/src/main/java/point/rar/adapter/WikiResponse.java b/wiki-game-common/src/main/java/point/rar/adapter/WikiResponse.java deleted file mode 100644 index 472d73c..0000000 --- a/wiki-game-common/src/main/java/point/rar/adapter/WikiResponse.java +++ /dev/null @@ -1,4 +0,0 @@ -package point.rar.adapter; - -public record WikiResponse() { -} diff --git a/wiki-game-common/src/main/java/point/rar/Main.java b/wiki-game-common/src/main/java/point/rar/common/Main.java similarity index 81% rename from wiki-game-common/src/main/java/point/rar/Main.java rename to wiki-game-common/src/main/java/point/rar/common/Main.java index 23ff025..bbf6a58 100644 --- a/wiki-game-common/src/main/java/point/rar/Main.java +++ b/wiki-game-common/src/main/java/point/rar/common/Main.java @@ -1,4 +1,4 @@ -package point.rar; +package point.rar.common; public class Main { public static void main(String[] args) { diff --git a/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/Link.kt b/wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/Link.kt similarity index 70% rename from wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/Link.kt rename to wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/Link.kt index 6329a20..2469c5d 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/Link.kt +++ b/wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/Link.kt @@ -1,4 +1,4 @@ -package point.rar.wiki.domain.model +package point.rar.common.wiki.domain.model import kotlinx.serialization.Serializable diff --git a/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/Page.kt b/wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/Page.kt similarity index 57% rename from wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/Page.kt rename to wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/Page.kt index 579c302..7487ec3 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/Page.kt +++ b/wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/Page.kt @@ -1,3 +1,3 @@ -package point.rar.wiki.domain.model +package point.rar.common.wiki.domain.model data class Page(val title: String, val parentPage: Page?) diff --git a/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/PageLinks.kt b/wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/PageLinks.kt similarity index 74% rename from wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/PageLinks.kt rename to wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/PageLinks.kt index 56616f2..57f0f5c 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/PageLinks.kt +++ b/wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/PageLinks.kt @@ -1,4 +1,4 @@ -package point.rar.wiki.domain.model +package point.rar.common.wiki.domain.model import kotlinx.serialization.Serializable diff --git a/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/QueryBacklinks.kt b/wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/QueryBacklinks.kt similarity index 73% rename from wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/QueryBacklinks.kt rename to wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/QueryBacklinks.kt index 2cdd376..56ad7f4 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/QueryBacklinks.kt +++ b/wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/QueryBacklinks.kt @@ -1,4 +1,4 @@ -package point.rar.wiki.domain.model +package point.rar.common.wiki.domain.model import kotlinx.serialization.Serializable diff --git a/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/QueryLinks.kt b/wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/QueryLinks.kt similarity index 75% rename from wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/QueryLinks.kt rename to wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/QueryLinks.kt index 50064cc..6500262 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/QueryLinks.kt +++ b/wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/QueryLinks.kt @@ -1,4 +1,4 @@ -package point.rar.wiki.domain.model +package point.rar.common.wiki.domain.model import kotlinx.serialization.Serializable diff --git a/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/WikiBacklinksResponse.kt b/wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/WikiBacklinksResponse.kt similarity index 74% rename from wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/WikiBacklinksResponse.kt rename to wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/WikiBacklinksResponse.kt index b4ba23c..9421fd6 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/WikiBacklinksResponse.kt +++ b/wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/WikiBacklinksResponse.kt @@ -1,4 +1,4 @@ -package point.rar.wiki.domain.model +package point.rar.common.wiki.domain.model import kotlinx.serialization.Serializable diff --git a/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/WikiLinksResponse.kt b/wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/WikiLinksResponse.kt similarity index 76% rename from wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/WikiLinksResponse.kt rename to wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/WikiLinksResponse.kt index eff9443..2c70ca6 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/wiki/domain/model/WikiLinksResponse.kt +++ b/wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/WikiLinksResponse.kt @@ -1,4 +1,4 @@ -package point.rar.wiki.domain.model +package point.rar.common.wiki.domain.model import kotlinx.serialization.Serializable diff --git a/wiki-game-common/src/main/java/point/rar/domain/Page.java b/wiki-game-common/src/main/java/point/rar/domain/Page.java deleted file mode 100644 index 56e0fcc..0000000 --- a/wiki-game-common/src/main/java/point/rar/domain/Page.java +++ /dev/null @@ -1,4 +0,0 @@ -package point.rar.domain; - -public record Page() { -} diff --git a/wiki-game-common/src/main/java/point/rar/domain/model/Link.java b/wiki-game-common/src/main/java/point/rar/domain/model/Link.java deleted file mode 100644 index dea5afe..0000000 --- a/wiki-game-common/src/main/java/point/rar/domain/model/Link.java +++ /dev/null @@ -1,4 +0,0 @@ -package point.rar.domain.model; - -record Link(String title){ -} diff --git a/wiki-game-common/src/main/java/point/rar/domain/model/PageLinks.java b/wiki-game-common/src/main/java/point/rar/domain/model/PageLinks.java deleted file mode 100644 index 4d00040..0000000 --- a/wiki-game-common/src/main/java/point/rar/domain/model/PageLinks.java +++ /dev/null @@ -1,6 +0,0 @@ -package point.rar.domain.model; - -import java.util.List; - -record PageLinks(List links) { -} diff --git a/wiki-game-common/src/main/java/point/rar/domain/model/QueryBacklinks.java b/wiki-game-common/src/main/java/point/rar/domain/model/QueryBacklinks.java deleted file mode 100644 index 83bac8a..0000000 --- a/wiki-game-common/src/main/java/point/rar/domain/model/QueryBacklinks.java +++ /dev/null @@ -1,7 +0,0 @@ -package point.rar.domain.model; - -import java.util.List; - -record QueryBacklinks(List backlinks){ - -} diff --git a/wiki-game-common/src/main/java/point/rar/domain/model/QueryLinks.java b/wiki-game-common/src/main/java/point/rar/domain/model/QueryLinks.java deleted file mode 100644 index c2714b9..0000000 --- a/wiki-game-common/src/main/java/point/rar/domain/model/QueryLinks.java +++ /dev/null @@ -1,8 +0,0 @@ -package point.rar.domain.model; - -import point.rar.domain.model.PageLinks; - -import java.util.Map; - -record QueryLinks(Map pages){ -} diff --git a/wiki-game-common/src/main/java/point/rar/domain/model/WikiBacklinksResponse.java b/wiki-game-common/src/main/java/point/rar/domain/model/WikiBacklinksResponse.java deleted file mode 100644 index 45ab8ea..0000000 --- a/wiki-game-common/src/main/java/point/rar/domain/model/WikiBacklinksResponse.java +++ /dev/null @@ -1,4 +0,0 @@ -package point.rar.domain.model; - -record WikiBacklinksResponse(QueryBacklinks query) { -} diff --git a/wiki-game-common/src/main/java/point/rar/domain/model/WikiLinksResponse.java b/wiki-game-common/src/main/java/point/rar/domain/model/WikiLinksResponse.java deleted file mode 100644 index 475740e..0000000 --- a/wiki-game-common/src/main/java/point/rar/domain/model/WikiLinksResponse.java +++ /dev/null @@ -1,4 +0,0 @@ -package point.rar.domain.model; - -record WikiLinksResponse(QueryLinks query) { -} \ No newline at end of file diff --git a/wiki-game-completable-feature/pom.xml b/wiki-game-completable-feature/pom.xml index 0ddac0a..7c4b507 100644 --- a/wiki-game-completable-feature/pom.xml +++ b/wiki-game-completable-feature/pom.xml @@ -12,8 +12,8 @@ wiki-game-completable-feature - 20 - 20 + 19 + 19 UTF-8 1.9.0 @@ -30,11 +30,6 @@ ${kotlin.version} test - - point.rar - wiki-game-completable-feature - 1.0-SNAPSHOT - com.fasterxml.jackson.dataformat jackson-dataformat-xml @@ -43,7 +38,12 @@ org.apache.httpcomponents httpclient - 4.5.1 + 4.5.13 + + + point.rar.common + wiki-game-common + 1.0-SNAPSHOT @@ -56,7 +56,7 @@ compile - compile + process-sources compile @@ -92,10 +92,6 @@ - - 19 - 19 - diff --git a/wiki-game-completable-feature/src/main/java/point/rar/Main.java b/wiki-game-completable-feature/src/main/java/point/rar/feature/Main.java similarity index 94% rename from wiki-game-completable-feature/src/main/java/point/rar/Main.java rename to wiki-game-completable-feature/src/main/java/point/rar/feature/Main.java index 06a39e0..7ec4877 100644 --- a/wiki-game-completable-feature/src/main/java/point/rar/Main.java +++ b/wiki-game-completable-feature/src/main/java/point/rar/feature/Main.java @@ -1,4 +1,4 @@ -package point.rar; +package point.rar.feature; public class Main { public static void main(String[] args) { diff --git a/wiki-game-completable-feature/src/main/java/point/rar/WikiGame.kt b/wiki-game-completable-feature/src/main/java/point/rar/feature/WikiGame.kt similarity index 81% rename from wiki-game-completable-feature/src/main/java/point/rar/WikiGame.kt rename to wiki-game-completable-feature/src/main/java/point/rar/feature/WikiGame.kt index 664e689..e89d78c 100644 --- a/wiki-game-completable-feature/src/main/java/point/rar/WikiGame.kt +++ b/wiki-game-completable-feature/src/main/java/point/rar/feature/WikiGame.kt @@ -1,4 +1,4 @@ -package point.rar +package point.rar.feature interface WikiGame { fun play(startPageTitle: String, endPageTitle: String, maxDepth: Int = 11): List diff --git a/wiki-game-completable-feature/src/main/java/point/rar/WikiGameFutureImpl.java b/wiki-game-completable-feature/src/main/java/point/rar/feature/WikiGameFutureImpl.java similarity index 96% rename from wiki-game-completable-feature/src/main/java/point/rar/WikiGameFutureImpl.java rename to wiki-game-completable-feature/src/main/java/point/rar/feature/WikiGameFutureImpl.java index 56a903c..f29ecbc 100644 --- a/wiki-game-completable-feature/src/main/java/point/rar/WikiGameFutureImpl.java +++ b/wiki-game-completable-feature/src/main/java/point/rar/feature/WikiGameFutureImpl.java @@ -1,12 +1,9 @@ -package point.rar; +package point.rar.feature; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.http.client.utils.URIBuilder; import org.jetbrains.annotations.NotNull; -import point.rar.wiki.domain.model.Link; -import point.rar.wiki.domain.model.Page; -import point.rar.wiki.domain.model.WikiLinksResponse; import java.io.IOException; import java.net.URI; diff --git a/wiki-game-completable-feature/src/main/java/point/rar/WikiGameSerialImpl.java b/wiki-game-completable-feature/src/main/java/point/rar/feature/WikiGameSerialImpl.java similarity index 95% rename from wiki-game-completable-feature/src/main/java/point/rar/WikiGameSerialImpl.java rename to wiki-game-completable-feature/src/main/java/point/rar/feature/WikiGameSerialImpl.java index b09c00e..d81f6b6 100644 --- a/wiki-game-completable-feature/src/main/java/point/rar/WikiGameSerialImpl.java +++ b/wiki-game-completable-feature/src/main/java/point/rar/feature/WikiGameSerialImpl.java @@ -1,11 +1,8 @@ -package point.rar; +package point.rar.feature; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import org.jetbrains.annotations.NotNull; -import point.rar.wiki.domain.model.Link; -import point.rar.wiki.domain.model.Page; -import point.rar.wiki.domain.model.WikiLinksResponse; import java.io.IOException; import java.net.URI; diff --git a/wiki-game-coroutines/src/main/java/point/rar/Main.kt b/wiki-game-coroutines/src/main/java/point/rar/coroutines/Main.kt similarity index 69% rename from wiki-game-coroutines/src/main/java/point/rar/Main.kt rename to wiki-game-coroutines/src/main/java/point/rar/coroutines/Main.kt index a93d1ef..7e83c8a 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/Main.kt +++ b/wiki-game-coroutines/src/main/java/point/rar/coroutines/Main.kt @@ -1,7 +1,7 @@ -package point.rar +package point.rar.coroutines -import point.rar.game.repository.WikiGame -import point.rar.game.repository.WikiGameDumbImpl +import point.rar.coroutines.repository.WikiGame +import point.rar.coroutines.repository.WikiGameDumbImpl fun main(args: Array) { val wikiGame: WikiGame = WikiGameDumbImpl() diff --git a/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGame.kt b/wiki-game-coroutines/src/main/java/point/rar/coroutines/repository/WikiGame.kt similarity index 74% rename from wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGame.kt rename to wiki-game-coroutines/src/main/java/point/rar/coroutines/repository/WikiGame.kt index 4957811..e5e08ef 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGame.kt +++ b/wiki-game-coroutines/src/main/java/point/rar/coroutines/repository/WikiGame.kt @@ -1,4 +1,4 @@ -package point.rar.game.repository +package point.rar.coroutines.repository interface WikiGame { fun play(startPageTitle: String, endPageTitle: String, maxDepth: Int = 11): List diff --git a/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt b/wiki-game-coroutines/src/main/java/point/rar/coroutines/repository/WikiGameDumbImpl.kt similarity index 93% rename from wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt rename to wiki-game-coroutines/src/main/java/point/rar/coroutines/repository/WikiGameDumbImpl.kt index 3a4654d..2c07f7a 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/game/repository/WikiGameDumbImpl.kt +++ b/wiki-game-coroutines/src/main/java/point/rar/coroutines/repository/WikiGameDumbImpl.kt @@ -1,10 +1,10 @@ -package point.rar.game.repository +package point.rar.coroutines.repository import kotlinx.coroutines.* import kotlinx.coroutines.channels.Channel -import point.rar.wiki.data.source.WikiRemoteDataSource -import point.rar.wiki.domain.model.Page -import point.rar.wiki.remote.WikiRemoteDataSourceImpl +import point.rar.coroutines.wiki.data.source.WikiRemoteDataSource +import point.rar.coroutines.wiki.domain.model.Page +import point.rar.coroutines.wiki.WikiRemoteDataSourceImpl import java.lang.RuntimeException import java.util.Optional import java.util.concurrent.ConcurrentHashMap diff --git a/wiki-game-coroutines/src/main/java/point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt b/wiki-game-coroutines/src/main/java/point/rar/coroutines/wiki/WikiRemoteDataSourceImpl.kt similarity index 92% rename from wiki-game-coroutines/src/main/java/point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt rename to wiki-game-coroutines/src/main/java/point/rar/coroutines/wiki/WikiRemoteDataSourceImpl.kt index 227f955..db04fa4 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/wiki/remote/WikiRemoteDataSourceImpl.kt +++ b/wiki-game-coroutines/src/main/java/point/rar/coroutines/wiki/WikiRemoteDataSourceImpl.kt @@ -1,4 +1,4 @@ -package point.rar.wiki.remote +package point.rar.coroutines.wiki import io.github.resilience4j.kotlin.ratelimiter.executeSuspendFunction import io.github.resilience4j.ratelimiter.RateLimiterConfig @@ -11,9 +11,6 @@ import io.ktor.client.request.get import io.ktor.client.request.parameter import io.ktor.serialization.kotlinx.json.json import kotlinx.serialization.json.Json -import point.rar.wiki.data.source.WikiRemoteDataSource -import point.rar.wiki.domain.model.WikiBacklinksResponse -import point.rar.wiki.domain.model.WikiLinksResponse import java.time.Duration class WikiRemoteDataSourceImpl : WikiRemoteDataSource { diff --git a/wiki-game-coroutines/src/main/java/point/rar/wiki/data/source/WikiRemoteDataSource.kt b/wiki-game-coroutines/src/main/java/point/rar/coroutines/wiki/data/source/WikiRemoteDataSource.kt similarity index 77% rename from wiki-game-coroutines/src/main/java/point/rar/wiki/data/source/WikiRemoteDataSource.kt rename to wiki-game-coroutines/src/main/java/point/rar/coroutines/wiki/data/source/WikiRemoteDataSource.kt index a79d761..bdbafd2 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/wiki/data/source/WikiRemoteDataSource.kt +++ b/wiki-game-coroutines/src/main/java/point/rar/coroutines/wiki/data/source/WikiRemoteDataSource.kt @@ -1,4 +1,4 @@ -package point.rar.wiki.data.source +package point.rar.coroutines.wiki.data.source interface WikiRemoteDataSource { suspend fun getLinksByTitle(title: String): List From 9209455d7e324f4c62140731c2a602704fa73c17 Mon Sep 17 00:00:00 2001 From: Daniil Lyubaev Date: Mon, 31 Jul 2023 22:17:09 +0300 Subject: [PATCH 24/58] fatJar --- wiki-game-completable-feature/pom.xml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/wiki-game-completable-feature/pom.xml b/wiki-game-completable-feature/pom.xml index 7c4b507..7a50fa1 100644 --- a/wiki-game-completable-feature/pom.xml +++ b/wiki-game-completable-feature/pom.xml @@ -93,6 +93,28 @@ + + + org.apache.maven.plugins + maven-assembly-plugin + 3.1.1 + + + + jar-with-dependencies + + + + + + make-assembly + package + + single + + + + From 101e6a7c43a90c37c19ec2b4fce52fc685a7489c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A8=D0=B0=D1=85=D0=BE=D0=B2=20=D0=90=D0=BB=D0=B5=D0=BA?= =?UTF-8?q?=D1=81=D0=B0=D0=BD=D0=B4=D1=80?= Date: Mon, 31 Jul 2023 23:49:51 +0300 Subject: [PATCH 25/58] Fix dependency --- wiki-game-common/pom.xml | 31 +++++++++---------- wiki-game-completable-feature/pom.xml | 24 +------------- .../point/rar/feature/WikiGameFutureImpl.java | 3 ++ .../point/rar/feature/WikiGameSerialImpl.java | 3 ++ wiki-game-coroutines/build.gradle.kts | 2 ++ .../coroutines/repository/WikiGameDumbImpl.kt | 2 +- .../wiki/WikiRemoteDataSourceImpl.kt | 3 ++ 7 files changed, 27 insertions(+), 41 deletions(-) diff --git a/wiki-game-common/pom.xml b/wiki-game-common/pom.xml index e5ac831..6316322 100644 --- a/wiki-game-common/pom.xml +++ b/wiki-game-common/pom.xml @@ -6,8 +6,8 @@ point.rar.common wiki-game-common - 1.0-SNAPSHOT - pom + 2.0 + jar 19 19 @@ -86,21 +86,18 @@ org.apache.maven.plugins - maven-dependency-plugin - - - copy-dependencies - prepare-package - - copy-dependencies - - - - ${project.build.directory}/libs - - - - + maven-jar-plugin + + + + true + libs/ + + point.rar.common.Main + + + + diff --git a/wiki-game-completable-feature/pom.xml b/wiki-game-completable-feature/pom.xml index 7a50fa1..b7ce12b 100644 --- a/wiki-game-completable-feature/pom.xml +++ b/wiki-game-completable-feature/pom.xml @@ -43,7 +43,7 @@ point.rar.common wiki-game-common - 1.0-SNAPSHOT + 2.0 @@ -93,28 +93,6 @@ - - - org.apache.maven.plugins - maven-assembly-plugin - 3.1.1 - - - - jar-with-dependencies - - - - - - make-assembly - package - - single - - - - diff --git a/wiki-game-completable-feature/src/main/java/point/rar/feature/WikiGameFutureImpl.java b/wiki-game-completable-feature/src/main/java/point/rar/feature/WikiGameFutureImpl.java index f29ecbc..2b7acb7 100644 --- a/wiki-game-completable-feature/src/main/java/point/rar/feature/WikiGameFutureImpl.java +++ b/wiki-game-completable-feature/src/main/java/point/rar/feature/WikiGameFutureImpl.java @@ -4,6 +4,9 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.http.client.utils.URIBuilder; import org.jetbrains.annotations.NotNull; +import point.rar.common.wiki.domain.model.Page; +import point.rar.common.wiki.domain.model.Link; +import point.rar.common.wiki.domain.model.WikiLinksResponse; import java.io.IOException; import java.net.URI; diff --git a/wiki-game-completable-feature/src/main/java/point/rar/feature/WikiGameSerialImpl.java b/wiki-game-completable-feature/src/main/java/point/rar/feature/WikiGameSerialImpl.java index d81f6b6..431378b 100644 --- a/wiki-game-completable-feature/src/main/java/point/rar/feature/WikiGameSerialImpl.java +++ b/wiki-game-completable-feature/src/main/java/point/rar/feature/WikiGameSerialImpl.java @@ -3,6 +3,9 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import org.jetbrains.annotations.NotNull; +import point.rar.common.wiki.domain.model.Page; +import point.rar.common.wiki.domain.model.Link; +import point.rar.common.wiki.domain.model.WikiLinksResponse; import java.io.IOException; import java.net.URI; diff --git a/wiki-game-coroutines/build.gradle.kts b/wiki-game-coroutines/build.gradle.kts index b76cee9..1afe23c 100644 --- a/wiki-game-coroutines/build.gradle.kts +++ b/wiki-game-coroutines/build.gradle.kts @@ -10,10 +10,12 @@ group = "point.rar" version = "1.0-SNAPSHOT" repositories { + mavenLocal() mavenCentral() } dependencies { + implementation("point.rar.common:wiki-game-common:2.0") implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.14.2") testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.1") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.1") diff --git a/wiki-game-coroutines/src/main/java/point/rar/coroutines/repository/WikiGameDumbImpl.kt b/wiki-game-coroutines/src/main/java/point/rar/coroutines/repository/WikiGameDumbImpl.kt index 2c07f7a..b3a74bc 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/coroutines/repository/WikiGameDumbImpl.kt +++ b/wiki-game-coroutines/src/main/java/point/rar/coroutines/repository/WikiGameDumbImpl.kt @@ -2,8 +2,8 @@ package point.rar.coroutines.repository import kotlinx.coroutines.* import kotlinx.coroutines.channels.Channel +import point.rar.common.wiki.domain.model.Page import point.rar.coroutines.wiki.data.source.WikiRemoteDataSource -import point.rar.coroutines.wiki.domain.model.Page import point.rar.coroutines.wiki.WikiRemoteDataSourceImpl import java.lang.RuntimeException import java.util.Optional diff --git a/wiki-game-coroutines/src/main/java/point/rar/coroutines/wiki/WikiRemoteDataSourceImpl.kt b/wiki-game-coroutines/src/main/java/point/rar/coroutines/wiki/WikiRemoteDataSourceImpl.kt index db04fa4..71fb4b3 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/coroutines/wiki/WikiRemoteDataSourceImpl.kt +++ b/wiki-game-coroutines/src/main/java/point/rar/coroutines/wiki/WikiRemoteDataSourceImpl.kt @@ -11,6 +11,9 @@ import io.ktor.client.request.get import io.ktor.client.request.parameter import io.ktor.serialization.kotlinx.json.json import kotlinx.serialization.json.Json +import point.rar.common.wiki.domain.model.WikiBacklinksResponse +import point.rar.common.wiki.domain.model.WikiLinksResponse +import point.rar.coroutines.wiki.data.source.WikiRemoteDataSource import java.time.Duration class WikiRemoteDataSourceImpl : WikiRemoteDataSource { From ff074b4bcdb04b85fdd662239e8810842734dc42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A8=D0=B0=D1=85=D0=BE=D0=B2=20=D0=90=D0=BB=D0=B5=D0=BA?= =?UTF-8?q?=D1=81=D0=B0=D0=BD=D0=B4=D1=80?= Date: Mon, 21 Aug 2023 00:28:05 +0300 Subject: [PATCH 26/58] Executors --- wiki-game-common/pom.xml | 5 + .../rar/feature/WikiGameFutureSimpleImpl.java | 137 ++++++++++++++++++ wiki-game-executor/.gitignore | 38 +++++ wiki-game-executor/pom.xml | 104 +++++++++++++ .../src/main/java/point/rar/feature/Main.java | 13 ++ .../main/java/point/rar/feature/WikiGame.kt | 5 + .../rar/feature/WikiGameExecutorImpl.java | 118 +++++++++++++++ .../point/rar/feature/WikiGameSerialImpl.java | 89 ++++++++++++ 8 files changed, 509 insertions(+) create mode 100644 wiki-game-completable-feature/src/main/java/point/rar/feature/WikiGameFutureSimpleImpl.java create mode 100644 wiki-game-executor/.gitignore create mode 100644 wiki-game-executor/pom.xml create mode 100644 wiki-game-executor/src/main/java/point/rar/feature/Main.java create mode 100644 wiki-game-executor/src/main/java/point/rar/feature/WikiGame.kt create mode 100644 wiki-game-executor/src/main/java/point/rar/feature/WikiGameExecutorImpl.java create mode 100644 wiki-game-executor/src/main/java/point/rar/feature/WikiGameSerialImpl.java diff --git a/wiki-game-common/pom.xml b/wiki-game-common/pom.xml index 6316322..3d91cd0 100644 --- a/wiki-game-common/pom.xml +++ b/wiki-game-common/pom.xml @@ -25,6 +25,11 @@ resilience4j-ratelimiter 2.1.0 + + io.github.resilience4j + resilience4j-timelimiter + 2.1.0 + com.fasterxml.jackson.core jackson-core diff --git a/wiki-game-completable-feature/src/main/java/point/rar/feature/WikiGameFutureSimpleImpl.java b/wiki-game-completable-feature/src/main/java/point/rar/feature/WikiGameFutureSimpleImpl.java new file mode 100644 index 0000000..6d49c76 --- /dev/null +++ b/wiki-game-completable-feature/src/main/java/point/rar/feature/WikiGameFutureSimpleImpl.java @@ -0,0 +1,137 @@ +package point.rar.feature; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import io.github.resilience4j.core.functions.CheckedRunnable; +import io.github.resilience4j.ratelimiter.RateLimiter; +import io.github.resilience4j.ratelimiter.RateLimiterConfig; +import io.github.resilience4j.ratelimiter.RateLimiterRegistry; +import org.apache.http.client.utils.URIBuilder; +import org.jetbrains.annotations.NotNull; +import point.rar.common.wiki.domain.model.Link; +import point.rar.common.wiki.domain.model.Page; +import point.rar.common.wiki.domain.model.WikiLinksResponse; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; +import java.util.*; +import java.util.concurrent.*; + +public class WikiGameFutureSimpleImpl implements WikiGame { + private static final String URL = "https://ru.wikipedia.org/w/api.php"; + + @NotNull + @Override + public List play(String startPageTitle, String endPageTitle, int maxDepth) { + var startedPage = new Page(startPageTitle, null); + Queue rawPages = new ConcurrentLinkedQueue<>(Collections.singleton(startedPage)); + Queue parsedPages = new ConcurrentLinkedQueue<>(); + Set parsedTitle = new ConcurrentSkipListSet<>(); + List> futures = new ArrayList<>(); + + RateLimiterConfig config = RateLimiterConfig.custom() + .limitRefreshPeriod(Duration.ofMillis(1000)) + .limitForPeriod(300) + .timeoutDuration(Duration.ofMillis(25)) + .build(); + RateLimiterRegistry rateLimiterRegistry = RateLimiterRegistry.of(config); + RateLimiter rateLimiter = rateLimiterRegistry + .rateLimiter("rateLimiter", config); + + + ExecutorService executorService = Executors.newVirtualThreadPerTaskExecutor(); + do { + for (int i = 0; i < 1000; i++) { + Page curPage = rawPages.poll(); + if (curPage == null) { + break; + } + Runnable restrictedCall = RateLimiter + .decorateRunnable(rateLimiter, makeSearch(curPage, rawPages, parsedPages, parsedTitle)); + CompletableFuture future =CompletableFuture.runAsync(restrictedCall); + futures.add(future); + } + CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join(); + futures.clear(); + } while (!parsedTitle.contains(endPageTitle)); + parsedPages.add( + new Page(endPageTitle, + rawPages.stream() + .filter(p -> p.getTitle().equals(endPageTitle)) + .findAny() + .orElseThrow() + ) + ); + + executorService.shutdown(); + return getResultPath(parsedPages, endPageTitle); + } + + private Runnable makeSearch(Page curPage, Queue rawPages, Queue parsedPages, Set parsedTitle) { + return () -> { + List newLinks = getChildLinks(curPage.getTitle()); + parsedPages.add(curPage); + parsedTitle.addAll(newLinks); + rawPages.addAll(newLinks.stream() + .map(m -> new Page(m, curPage)) + .toList()); + }; + } + + private List getResultPath(Queue parsedPages, String endPageTitle) { + var path = new ArrayList(); + var curPage = parsedPages.stream() + .filter(p -> p.getTitle().equals(endPageTitle)) + .findAny() + .orElseThrow(); + while (curPage.getParentPage() != null) { + curPage = curPage.getParentPage(); + path.add(curPage.getTitle()); + } + Collections.reverse(path); // Reverse the order of elements in the list + return path; + } + + + private static List getChildLinks(String title) { + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + + + String responseBody = null; + try { + URIBuilder uriBuilder = new URIBuilder(URL); + uriBuilder.addParameter("action", "query"); + uriBuilder.addParameter("prop", "links"); + uriBuilder.addParameter("pllimit", "max"); + uriBuilder.addParameter("format", "json"); + uriBuilder.addParameter("plnamespace", "titles"); + + System.out.println("Get links for: " + title); + responseBody = HttpClient.newBuilder() + .build() + .sendAsync(HttpRequest.newBuilder() + .uri(URI.create(uriBuilder.addParameter("titles", title).build().toString())) + .GET() + .build(), HttpResponse.BodyHandlers.ofString()).get().body(); + var response = objectMapper.readValue(responseBody, WikiLinksResponse.class); + + return parseLinks(response); + } catch (IOException | InterruptedException | URISyntaxException | ExecutionException e) { + throw new RuntimeException(e); + } + } + + @NotNull + private static List parseLinks(WikiLinksResponse response) { + return response.getQuery().getPages().entrySet().iterator().next().getValue().getLinks() + .stream() + .map(Link::getTitle) + .toList(); + } +} diff --git a/wiki-game-executor/.gitignore b/wiki-game-executor/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/wiki-game-executor/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/wiki-game-executor/pom.xml b/wiki-game-executor/pom.xml new file mode 100644 index 0000000..8156d1b --- /dev/null +++ b/wiki-game-executor/pom.xml @@ -0,0 +1,104 @@ + + + 4.0.0 + + point.rar + wiki-game-common + 1.0-SNAPSHOT + + + wiki-game-execotor + + + 19 + 19 + UTF-8 + 1.9.0 + + + + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-test + ${kotlin.version} + test + + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + 2.14.2 + + + org.apache.httpcomponents + httpclient + 4.5.13 + + + com.google.guava + guava + 31.0.1-jre + + + point.rar.common + wiki-game-common + 2.0 + + + + + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + compile + process-sources + + compile + + + + test-compile + test-compile + + test-compile + + + + + ${maven.compiler.target} + + + + org.apache.maven.plugins + maven-compiler-plugin + + + compile + compile + + compile + + + + testCompile + test-compile + + testCompile + + + + + + + + \ No newline at end of file diff --git a/wiki-game-executor/src/main/java/point/rar/feature/Main.java b/wiki-game-executor/src/main/java/point/rar/feature/Main.java new file mode 100644 index 0000000..1ad37f4 --- /dev/null +++ b/wiki-game-executor/src/main/java/point/rar/feature/Main.java @@ -0,0 +1,13 @@ +package point.rar.feature; + +public class Main { + public static void main(String[] args) { + long startTime = System.currentTimeMillis(); + WikiGame wikiGame = new WikiGameExecutorImpl(); +// var path = wikiGame.play("Алгебра", "Ятаган", 6); + var path = wikiGame.play("Бакуган", "Библия", 6); + System.out.println(path); + long endTime = System.currentTimeMillis(); + System.out.println("Total execution time: " + (endTime - startTime) + "ms"); + } +} \ No newline at end of file diff --git a/wiki-game-executor/src/main/java/point/rar/feature/WikiGame.kt b/wiki-game-executor/src/main/java/point/rar/feature/WikiGame.kt new file mode 100644 index 0000000..e89d78c --- /dev/null +++ b/wiki-game-executor/src/main/java/point/rar/feature/WikiGame.kt @@ -0,0 +1,5 @@ +package point.rar.feature + +interface WikiGame { + fun play(startPageTitle: String, endPageTitle: String, maxDepth: Int = 11): List +} \ No newline at end of file diff --git a/wiki-game-executor/src/main/java/point/rar/feature/WikiGameExecutorImpl.java b/wiki-game-executor/src/main/java/point/rar/feature/WikiGameExecutorImpl.java new file mode 100644 index 0000000..ecf2ecc --- /dev/null +++ b/wiki-game-executor/src/main/java/point/rar/feature/WikiGameExecutorImpl.java @@ -0,0 +1,118 @@ +package point.rar.feature; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.util.concurrent.RateLimiter; +import org.apache.http.client.utils.URIBuilder; +import org.jetbrains.annotations.NotNull; +import point.rar.common.wiki.domain.model.Page; +import point.rar.common.wiki.domain.model.Link; +import point.rar.common.wiki.domain.model.WikiLinksResponse; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; +import java.util.*; +import java.util.concurrent.*; + +public class WikiGameExecutorImpl implements WikiGame { + private static final String URL = "https://ru.wikipedia.org/w/api.php"; + private static final RateLimiter rateLimiter = RateLimiter.create(100); + + @NotNull + @Override + public List play(@NotNull String startPageTitle, @NotNull String endPageTitle, int maxDepth) { + var startedPage = new Page(startPageTitle, null); + Queue rawPages = new ConcurrentLinkedQueue<>(Collections.singleton(startedPage)); + Queue parsedPages = new ConcurrentLinkedQueue<>(); + Set receivedLinks = new ConcurrentSkipListSet<>(); + + +// ExecutorService exec = Executors.newCachedThreadPool(); +// ExecutorService exec = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() + 1); + ExecutorService exec = Executors.newVirtualThreadPerTaskExecutor(); + + do { + Page curPage = rawPages.poll(); + if (curPage != null) { + exec.execute(() -> makeSearch(curPage, rawPages, parsedPages, receivedLinks)); + } + } while (!receivedLinks.contains(endPageTitle)); + exec.shutdown(); + + parsedPages.add( + new Page(endPageTitle, + rawPages.stream() + .filter(p -> p.getTitle().equals(endPageTitle)) + .findAny() + .orElseThrow() + ) + ); + + return getResultPath(parsedPages, endPageTitle); + } + + private void makeSearch(Page curPage, Queue rawPages, Queue parsedPages, Set receivedLinks) { + List newLinks = getChildLinks(curPage.getTitle()); + parsedPages.add(curPage); + for (String link : newLinks) { + if (receivedLinks.add(link)) { + rawPages.add(new Page(link, curPage)); + } + } + } + + private List getResultPath(Queue parsedPages, String endPageTitle) { + var path = new ArrayList(); + var curPage = parsedPages.stream() + .filter(p -> p.getTitle().equals(endPageTitle)) + .findAny() + .orElseThrow(); + while (curPage.getParentPage() != null) { + curPage = curPage.getParentPage(); + path.add(curPage.getTitle()); + } + Collections.reverse(path); // Reverse the order of elements in the list + return path; + } + + + private List getChildLinks(String title) { + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + + try { + URIBuilder uriBuilder = new URIBuilder(URL); + uriBuilder.addParameter("action", "query"); + uriBuilder.addParameter("prop", "links"); + uriBuilder.addParameter("pllimit", "max"); + uriBuilder.addParameter("format", "json"); + uriBuilder.addParameter("plnamespace", "titles"); + + System.out.println("Get links for: " + title + ", acquire: " + rateLimiter.acquire()); + String responseBody = HttpClient.newBuilder() + .build() + .sendAsync(HttpRequest.newBuilder() + .uri(URI.create(uriBuilder.addParameter("titles", title).build().toString())) + .GET() + .build(), HttpResponse.BodyHandlers.ofString()).get().body(); + WikiLinksResponse response = objectMapper.readValue(responseBody, WikiLinksResponse.class); + + return parseLinks(response); + } catch (IOException | InterruptedException | URISyntaxException | ExecutionException e) { + throw new RuntimeException(e); + } + } + + @NotNull + private static List parseLinks(WikiLinksResponse response) { + return response.getQuery().getPages().entrySet().iterator().next().getValue().getLinks() + .stream() + .map(Link::getTitle) + .toList(); + } +} diff --git a/wiki-game-executor/src/main/java/point/rar/feature/WikiGameSerialImpl.java b/wiki-game-executor/src/main/java/point/rar/feature/WikiGameSerialImpl.java new file mode 100644 index 0000000..431378b --- /dev/null +++ b/wiki-game-executor/src/main/java/point/rar/feature/WikiGameSerialImpl.java @@ -0,0 +1,89 @@ +package point.rar.feature; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.jetbrains.annotations.NotNull; +import point.rar.common.wiki.domain.model.Page; +import point.rar.common.wiki.domain.model.Link; +import point.rar.common.wiki.domain.model.WikiLinksResponse; + +import java.io.IOException; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.util.*; + +public class WikiGameSerialImpl implements WikiGame { + private static final String URL = "https://ru.wikipedia.org/w/api.php"; + + @NotNull + @Override + public List play(String startPageTitle, String endPageTitle, int maxDepth) { + var startedPage = new Page(startPageTitle, null); + Queue rawPages = new LinkedList<>(Collections.singleton(startedPage)); + Queue parsedPages = new LinkedList<>(); + Set parsedTitle = new HashSet<>(); + var parentEndPage = startedPage; + do { + System.out.println("parsedPages size = " + parsedPages.size()); + System.out.println("rawPages size = " + rawPages.size()); + System.out.println("parsedTitle size = " + parsedTitle.size()); + var curPage = rawPages.poll(); + parentEndPage = curPage; + var newLinks = parseLinks(curPage.getTitle()); + parsedPages.add(curPage); + parsedTitle.addAll(newLinks); + rawPages.addAll( + newLinks.stream() + .map(m -> new Page(m, curPage)) + .toList() + ); + } while (!parsedTitle.contains(endPageTitle)); + parsedPages.add(new Page(endPageTitle, parentEndPage)); + + return getResultPath(parsedPages, endPageTitle); + } + + private List getResultPath(Queue parsedPages, String endPageTitle) { + var path = new ArrayList(); + var curPage = parsedPages.stream() + .filter(p -> p.getTitle().equals(endPageTitle)) + .findAny() + .orElseThrow(); + while (curPage.getParentPage() != null) { + path.add(curPage.getTitle()); + curPage = curPage.getParentPage(); + } + path.add(curPage.getTitle()); + return path; + } + + + private List parseLinks(String title) { + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + try { + System.out.println("Get links for: " + title); + String responseBody = HttpClient.newBuilder() + .build() + .send(HttpRequest.newBuilder() + .uri(URI.create(URL + "?action=query&prop=links&pllimit=max&format=json&plnamespace=0&titles=" + title.replace(" ", "%20"))) + .GET() + .build(), HttpResponse.BodyHandlers.ofString()).body(); + WikiLinksResponse response = objectMapper.readValue(responseBody, WikiLinksResponse.class); + + return parseLinks(response); + } catch (IOException | InterruptedException e) { + throw new RuntimeException(e); + } + } + + @NotNull + private static List parseLinks(WikiLinksResponse response) { + return response.getQuery().getPages().entrySet().iterator().next().getValue().getLinks() + .stream() + .map(Link::getTitle) + .toList(); + } +} From 5199e97f9900614c729d2cc12202e3155ef40734 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A8=D0=B0=D1=85=D0=BE=D0=B2=20=D0=90=D0=BB=D0=B5=D0=BA?= =?UTF-8?q?=D1=81=D0=B0=D0=BD=D0=B4=D1=80?= Date: Mon, 21 Aug 2023 02:51:34 +0300 Subject: [PATCH 27/58] Fix rateLimiter --- wiki-game-executor/pom.xml | 6 +- .../rar/feature/WikiGameExecutorImpl.java | 91 ++++++++++++------- 2 files changed, 63 insertions(+), 34 deletions(-) diff --git a/wiki-game-executor/pom.xml b/wiki-game-executor/pom.xml index 8156d1b..78de652 100644 --- a/wiki-game-executor/pom.xml +++ b/wiki-game-executor/pom.xml @@ -41,9 +41,9 @@ 4.5.13 - com.google.guava - guava - 31.0.1-jre + io.github.resilience4j + resilience4j-timelimiter + 2.1.0 point.rar.common diff --git a/wiki-game-executor/src/main/java/point/rar/feature/WikiGameExecutorImpl.java b/wiki-game-executor/src/main/java/point/rar/feature/WikiGameExecutorImpl.java index ecf2ecc..18883bd 100644 --- a/wiki-game-executor/src/main/java/point/rar/feature/WikiGameExecutorImpl.java +++ b/wiki-game-executor/src/main/java/point/rar/feature/WikiGameExecutorImpl.java @@ -2,7 +2,12 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.util.concurrent.RateLimiter; +import io.github.resilience4j.ratelimiter.RateLimiter; +import io.github.resilience4j.ratelimiter.RateLimiterConfig; +import io.github.resilience4j.ratelimiter.RateLimiterRegistry; +import io.github.resilience4j.retry.Retry; +import io.github.resilience4j.retry.RetryConfig; +import io.github.resilience4j.retry.RetryRegistry; import org.apache.http.client.utils.URIBuilder; import org.jetbrains.annotations.NotNull; import point.rar.common.wiki.domain.model.Page; @@ -21,7 +26,13 @@ public class WikiGameExecutorImpl implements WikiGame { private static final String URL = "https://ru.wikipedia.org/w/api.php"; - private static final RateLimiter rateLimiter = RateLimiter.create(100); + private static final RateLimiterConfig config = RateLimiterConfig.custom() + .limitRefreshPeriod(Duration.ofMillis(50)) + .limitForPeriod(10) + .timeoutDuration(Duration.ofMillis(5)) + .build(); + private static final RateLimiterRegistry rateLimiterRegistry = RateLimiterRegistry.of(config); + private static final RateLimiter rateLimiter = rateLimiterRegistry.rateLimiter("rate"); @NotNull @Override @@ -31,18 +42,17 @@ public List play(@NotNull String startPageTitle, @NotNull String endPage Queue parsedPages = new ConcurrentLinkedQueue<>(); Set receivedLinks = new ConcurrentSkipListSet<>(); - -// ExecutorService exec = Executors.newCachedThreadPool(); -// ExecutorService exec = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() + 1); ExecutorService exec = Executors.newVirtualThreadPerTaskExecutor(); do { Page curPage = rawPages.poll(); if (curPage != null) { - exec.execute(() -> makeSearch(curPage, rawPages, parsedPages, receivedLinks)); + exec.execute(makeSearch(curPage, rawPages, parsedPages, receivedLinks)); } + } while (!receivedLinks.contains(endPageTitle)); exec.shutdown(); + exec.close(); parsedPages.add( new Page(endPageTitle, @@ -56,17 +66,23 @@ public List play(@NotNull String startPageTitle, @NotNull String endPage return getResultPath(parsedPages, endPageTitle); } - private void makeSearch(Page curPage, Queue rawPages, Queue parsedPages, Set receivedLinks) { - List newLinks = getChildLinks(curPage.getTitle()); - parsedPages.add(curPage); - for (String link : newLinks) { - if (receivedLinks.add(link)) { - rawPages.add(new Page(link, curPage)); + public static Runnable makeSearch(Page curPage, Queue rawPages, Queue parsedPages, Set receivedLinks) { + return () -> { + List newLinks = getChildLinks(curPage.getTitle()); + if (newLinks != null) { + parsedPages.add(curPage); + for (String link : newLinks) { + if (receivedLinks.add(link)) { + rawPages.add(new Page(link, curPage)); + } + } + } else { + rawPages.add(curPage); } - } + }; } - private List getResultPath(Queue parsedPages, String endPageTitle) { + private static List getResultPath(Queue parsedPages, String endPageTitle) { var path = new ArrayList(); var curPage = parsedPages.stream() .filter(p -> p.getTitle().equals(endPageTitle)) @@ -81,33 +97,46 @@ private List getResultPath(Queue parsedPages, String endPageTitle) } - private List getChildLinks(String title) { + private static List getChildLinks(String title) { ObjectMapper objectMapper = new ObjectMapper(); objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); try { - URIBuilder uriBuilder = new URIBuilder(URL); - uriBuilder.addParameter("action", "query"); - uriBuilder.addParameter("prop", "links"); - uriBuilder.addParameter("pllimit", "max"); - uriBuilder.addParameter("format", "json"); - uriBuilder.addParameter("plnamespace", "titles"); - - System.out.println("Get links for: " + title + ", acquire: " + rateLimiter.acquire()); - String responseBody = HttpClient.newBuilder() - .build() - .sendAsync(HttpRequest.newBuilder() - .uri(URI.create(uriBuilder.addParameter("titles", title).build().toString())) - .GET() - .build(), HttpResponse.BodyHandlers.ofString()).get().body(); + System.out.println("Get links for: " + title); + System.out.println(rateLimiter.getMetrics().getAvailablePermissions()); + URIBuilder uriBuilder = getUriBuilder(); + String responseBody = makeRequest(title, uriBuilder); WikiLinksResponse response = objectMapper.readValue(responseBody, WikiLinksResponse.class); return parseLinks(response); - } catch (IOException | InterruptedException | URISyntaxException | ExecutionException e) { - throw new RuntimeException(e); + } catch (Throwable e) { + return null; } } + private static String makeRequest(String title, URIBuilder uriBuilder) throws Throwable { + return RateLimiter.decorateCheckedSupplier(rateLimiter, () -> HttpClient.newBuilder() + .build() + .sendAsync(HttpRequest.newBuilder() + .uri(URI.create(uriBuilder.addParameter("titles", title).build().toString())) + .GET() + .build(), + HttpResponse.BodyHandlers.ofString()) + .get() + .body()).get(); + } + + @NotNull + private static URIBuilder getUriBuilder() throws URISyntaxException { + URIBuilder uriBuilder = new URIBuilder(URL); + uriBuilder.addParameter("action", "query"); + uriBuilder.addParameter("prop", "links"); + uriBuilder.addParameter("pllimit", "max"); + uriBuilder.addParameter("format", "json"); + uriBuilder.addParameter("plnamespace", "titles"); + return uriBuilder; + } + @NotNull private static List parseLinks(WikiLinksResponse response) { return response.getQuery().getPages().entrySet().iterator().next().getValue().getLinks() From ae19b9910fe148af3fc68bc966ebe173b762cfd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A8=D0=B0=D1=85=D0=BE=D0=B2=20=D0=90=D0=BB=D0=B5=D0=BA?= =?UTF-8?q?=D1=81=D0=B0=D0=BD=D0=B4=D1=80?= Date: Mon, 21 Aug 2023 04:12:56 +0300 Subject: [PATCH 28/58] Fix preview --- .../rar/common/wiki/domain/model/Page.kt | 6 ++- wiki-game-executor/pom.xml | 6 +++ .../rar/feature/WikiGameExecutorImpl.java | 40 ++++++++++--------- 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/Page.kt b/wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/Page.kt index 7487ec3..184c91a 100644 --- a/wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/Page.kt +++ b/wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/Page.kt @@ -1,3 +1,7 @@ package point.rar.common.wiki.domain.model -data class Page(val title: String, val parentPage: Page?) +data class Page(val title: String, val parentPage: Page?) : Comparable { + override fun compareTo(other: Page): Int { + return title.compareTo(other.title) + } +} diff --git a/wiki-game-executor/pom.xml b/wiki-game-executor/pom.xml index 78de652..51346da 100644 --- a/wiki-game-executor/pom.xml +++ b/wiki-game-executor/pom.xml @@ -81,6 +81,12 @@ org.apache.maven.plugins maven-compiler-plugin + + + + --enable-preview + + compile diff --git a/wiki-game-executor/src/main/java/point/rar/feature/WikiGameExecutorImpl.java b/wiki-game-executor/src/main/java/point/rar/feature/WikiGameExecutorImpl.java index 18883bd..e514a8b 100644 --- a/wiki-game-executor/src/main/java/point/rar/feature/WikiGameExecutorImpl.java +++ b/wiki-game-executor/src/main/java/point/rar/feature/WikiGameExecutorImpl.java @@ -5,16 +5,12 @@ import io.github.resilience4j.ratelimiter.RateLimiter; import io.github.resilience4j.ratelimiter.RateLimiterConfig; import io.github.resilience4j.ratelimiter.RateLimiterRegistry; -import io.github.resilience4j.retry.Retry; -import io.github.resilience4j.retry.RetryConfig; -import io.github.resilience4j.retry.RetryRegistry; import org.apache.http.client.utils.URIBuilder; import org.jetbrains.annotations.NotNull; import point.rar.common.wiki.domain.model.Page; import point.rar.common.wiki.domain.model.Link; import point.rar.common.wiki.domain.model.WikiLinksResponse; -import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.net.http.HttpClient; @@ -23,6 +19,7 @@ import java.time.Duration; import java.util.*; import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicBoolean; public class WikiGameExecutorImpl implements WikiGame { private static final String URL = "https://ru.wikipedia.org/w/api.php"; @@ -34,6 +31,8 @@ public class WikiGameExecutorImpl implements WikiGame { private static final RateLimiterRegistry rateLimiterRegistry = RateLimiterRegistry.of(config); private static final RateLimiter rateLimiter = rateLimiterRegistry.rateLimiter("rate"); + private static AtomicBoolean isFinished = new AtomicBoolean(false); + @NotNull @Override public List play(@NotNull String startPageTitle, @NotNull String endPageTitle, int maxDepth) { @@ -45,12 +44,8 @@ public List play(@NotNull String startPageTitle, @NotNull String endPage ExecutorService exec = Executors.newVirtualThreadPerTaskExecutor(); do { - Page curPage = rawPages.poll(); - if (curPage != null) { - exec.execute(makeSearch(curPage, rawPages, parsedPages, receivedLinks)); - } - - } while (!receivedLinks.contains(endPageTitle)); + exec.execute(makeSearch(rawPages, parsedPages, receivedLinks, endPageTitle)); + } while (!isFinished.get()); exec.shutdown(); exec.close(); @@ -66,18 +61,25 @@ public List play(@NotNull String startPageTitle, @NotNull String endPage return getResultPath(parsedPages, endPageTitle); } - public static Runnable makeSearch(Page curPage, Queue rawPages, Queue parsedPages, Set receivedLinks) { + public static Runnable makeSearch(Queue rawPages, Queue parsedPages, Set receivedLinks, String endPageTitle) { return () -> { - List newLinks = getChildLinks(curPage.getTitle()); - if (newLinks != null) { - parsedPages.add(curPage); - for (String link : newLinks) { - if (receivedLinks.add(link)) { - rawPages.add(new Page(link, curPage)); + Page curPage = rawPages.poll(); + if (curPage != null) { + List newLinks = getChildLinks(curPage.getTitle()); + if (newLinks != null) { + parsedPages.add(curPage); + for (String link : newLinks) { + if (receivedLinks.add(link)) { + rawPages.add(new Page(link, curPage)); + } + if (endPageTitle.equals(link)) { + isFinished.set(true); + break; + } } + } else { + rawPages.add(curPage); } - } else { - rawPages.add(curPage); } }; } From e79012abacf5a77525a0e368d6d41841c666e976 Mon Sep 17 00:00:00 2001 From: Aleksandr Shakhov Date: Mon, 21 Aug 2023 16:01:20 +0300 Subject: [PATCH 29/58] Update README.md --- README.md | 47 +---------------------------------------------- 1 file changed, 1 insertion(+), 46 deletions(-) diff --git a/README.md b/README.md index 75769a3..2360331 100644 --- a/README.md +++ b/README.md @@ -1,48 +1,3 @@ Тезисы доклада: -1. Вступление - - Важность многопоточности в разработке Java-приложений - - Цель доклада: исследовать различные реализации многопоточности на примере игры WikiGame - -2. Обзор WikiGame - - Описание игры WikiGame и ее механики - - Задачи игрока и требования к реализации - -3. Преимущества и сложности многопоточности - - Обзор преимуществ параллельного программирования - - Вызовы и сложности, связанные с многопоточностью - -4. Реализация с использованием класса Thread - - Объяснение создания и запуска потоков с помощью класса Thread - - Демонстрация синхронизации потоков для безопасной работы с общими данными в WikiGame - - Примеры использования методов wait() и notify() - -5. Реализация с использованием Executor и ExecutorService - - Введение в Executor Framework и его преимущества - - Использование ExecutorService для управления пулом потоков в WikiGame - - Показ примеров использования ExecutorService для выполнения задач в фоновом режиме - -6. Реализация с использованием CompletableFuture - - Обзор возможностей CompletableFuture для асинхронного программирования - - Примеры использования CompletableFuture для параллельной обработки задач в WikiGame - - Обработка исключений и синхронизация результатов с использованием CompletableFuture - -7. Реализация с использованием Coroutines - - Введение в понятие Coroutines и их роль в асинхронном программировании - - Примеры использования Coroutines для реализации параллельных задач в WikiGame - - Преимущества и особенности использования Coroutines в контексте многопоточности - -8. Сравнение и анализ реализаций - - Сравнение производительности и простоты использования каждой реализации в WikiGame - - Обсуждение ограничений, преимуществ и недостатков каждого подхода - - Рекомендации по выбору наиболее подходящей реализации в зависимости от конкретных требований - -9. Заключение - - Подведение итогов и обобщение основных результатов доклада - - Значимость многопоточности в современном развитии Java-приложений - - -Fork/Join framework -Loom -RxJava -Actor Model +https://docs.google.com/document/d/1bVv3UhvC1sN2CfQNMLt70vazhxSSb7iKRNTMp-7QlO4/edit?usp=sharing From b68d2a8c2ac87ca13b36de5445edc987b4e7ad48 Mon Sep 17 00:00:00 2001 From: Daniil Lyubaev Date: Sat, 2 Sep 2023 19:50:28 +0300 Subject: [PATCH 30/58] all gradle --- wiki-game-common/pom.xml | 109 ----------- wiki-game-completable-feature/pom.xml | 99 ---------- wiki-game-coroutines/.gitignore | 2 - wiki-game-coroutines/settings.gradle.kts | 2 - wiki-game-executor/.gitignore | 38 ---- wiki-game-executor/pom.xml | 110 ----------- wikigame/.gradle/7.6/checksums/checksums.lock | Bin 0 -> 17 bytes .../dependencies-accessors.lock | Bin 0 -> 17 bytes .../7.6/dependencies-accessors/gc.properties | 0 .../7.6/executionHistory/executionHistory.bin | Bin 0 -> 109951 bytes .../executionHistory/executionHistory.lock | Bin 0 -> 17 bytes .../.gradle/7.6/fileChanges/last-build.bin | Bin 0 -> 1 bytes .../.gradle/7.6/fileHashes/fileHashes.bin | Bin 0 -> 31797 bytes .../.gradle/7.6/fileHashes/fileHashes.lock | Bin 0 -> 17 bytes .../7.6/fileHashes/resourceHashesCache.bin | Bin 0 -> 19857 bytes wikigame/.gradle/7.6/gc.properties | 0 .../buildOutputCleanup.lock | Bin 0 -> 17 bytes .../buildOutputCleanup/cache.properties | 2 + .../buildOutputCleanup/outputFiles.bin | Bin 0 -> 19919 bytes wikigame/.gradle/file-system.probe | Bin 0 -> 8 bytes wikigame/.gradle/vcs-1/gc.properties | 0 wikigame/build.gradle.kts | 28 +++ .../main/META-INF/wikigame.kotlin_module | Bin 0 -> 24 bytes .../caches-jvm/inputs/source-to-output.tab | Bin 0 -> 4096 bytes .../inputs/source-to-output.tab.keystream | Bin 0 -> 4096 bytes .../inputs/source-to-output.tab.keystream.len | Bin 0 -> 8 bytes .../inputs/source-to-output.tab.len | Bin 0 -> 8 bytes .../inputs/source-to-output.tab.values.at | Bin 0 -> 2131 bytes .../caches-jvm/inputs/source-to-output.tab_i | Bin 0 -> 32768 bytes .../inputs/source-to-output.tab_i.len | Bin 0 -> 8 bytes .../jvm/kotlin/class-attributes.tab | Bin 0 -> 4096 bytes .../jvm/kotlin/class-attributes.tab.keystream | Bin 0 -> 4096 bytes .../kotlin/class-attributes.tab.keystream.len | Bin 0 -> 8 bytes .../jvm/kotlin/class-attributes.tab.len | Bin 0 -> 8 bytes .../jvm/kotlin/class-attributes.tab.values.at | Bin 0 -> 106 bytes .../jvm/kotlin/class-attributes.tab_i | Bin 0 -> 32768 bytes .../jvm/kotlin/class-attributes.tab_i.len | Bin 0 -> 8 bytes .../jvm/kotlin/class-fq-name-to-source.tab | Bin 0 -> 4096 bytes .../class-fq-name-to-source.tab.keystream | Bin 0 -> 4096 bytes .../class-fq-name-to-source.tab.keystream.len | Bin 0 -> 8 bytes .../kotlin/class-fq-name-to-source.tab.len | Bin 0 -> 8 bytes .../class-fq-name-to-source.tab.values.at | Bin 0 -> 1228 bytes .../jvm/kotlin/class-fq-name-to-source.tab_i | Bin 0 -> 32768 bytes .../kotlin/class-fq-name-to-source.tab_i.len | Bin 0 -> 8 bytes .../jvm/kotlin/internal-name-to-source.tab | Bin 0 -> 4096 bytes .../internal-name-to-source.tab.keystream | Bin 0 -> 4096 bytes .../internal-name-to-source.tab.keystream.len | Bin 0 -> 8 bytes .../kotlin/internal-name-to-source.tab.len | Bin 0 -> 8 bytes .../internal-name-to-source.tab.values.at | Bin 0 -> 1228 bytes .../jvm/kotlin/internal-name-to-source.tab_i | Bin 0 -> 32768 bytes .../kotlin/internal-name-to-source.tab_i.len | Bin 0 -> 8 bytes .../cacheable/caches-jvm/jvm/kotlin/proto.tab | Bin 0 -> 4096 bytes .../caches-jvm/jvm/kotlin/proto.tab.keystream | Bin 0 -> 4096 bytes .../jvm/kotlin/proto.tab.keystream.len | Bin 0 -> 8 bytes .../caches-jvm/jvm/kotlin/proto.tab.len | Bin 0 -> 8 bytes .../caches-jvm/jvm/kotlin/proto.tab.values.at | Bin 0 -> 11251 bytes .../caches-jvm/jvm/kotlin/proto.tab_i | Bin 0 -> 32768 bytes .../caches-jvm/jvm/kotlin/proto.tab_i.len | Bin 0 -> 8 bytes .../jvm/kotlin/source-to-classes.tab | Bin 0 -> 4096 bytes .../kotlin/source-to-classes.tab.keystream | Bin 0 -> 4096 bytes .../source-to-classes.tab.keystream.len | Bin 0 -> 8 bytes .../jvm/kotlin/source-to-classes.tab.len | Bin 0 -> 8 bytes .../kotlin/source-to-classes.tab.values.at | Bin 0 -> 852 bytes .../jvm/kotlin/source-to-classes.tab_i | Bin 0 -> 32768 bytes .../jvm/kotlin/source-to-classes.tab_i.len | Bin 0 -> 8 bytes .../caches-jvm/jvm/kotlin/subtypes.tab | Bin 0 -> 4096 bytes .../jvm/kotlin/subtypes.tab.keystream | Bin 0 -> 4096 bytes .../jvm/kotlin/subtypes.tab.keystream.len | Bin 0 -> 8 bytes .../caches-jvm/jvm/kotlin/subtypes.tab.len | Bin 0 -> 8 bytes .../jvm/kotlin/subtypes.tab.values.at | Bin 0 -> 324 bytes .../caches-jvm/jvm/kotlin/subtypes.tab_i | Bin 0 -> 32768 bytes .../caches-jvm/jvm/kotlin/subtypes.tab_i.len | Bin 0 -> 8 bytes .../caches-jvm/jvm/kotlin/supertypes.tab | Bin 0 -> 4096 bytes .../jvm/kotlin/supertypes.tab.keystream | Bin 0 -> 4096 bytes .../jvm/kotlin/supertypes.tab.keystream.len | Bin 0 -> 8 bytes .../caches-jvm/jvm/kotlin/supertypes.tab.len | Bin 0 -> 8 bytes .../jvm/kotlin/supertypes.tab.values.at | Bin 0 -> 387 bytes .../caches-jvm/jvm/kotlin/supertypes.tab_i | Bin 0 -> 32768 bytes .../jvm/kotlin/supertypes.tab_i.len | Bin 0 -> 8 bytes .../cacheable/caches-jvm/lookups/counters.tab | 2 + .../caches-jvm/lookups/file-to-id.tab | Bin 0 -> 4096 bytes .../lookups/file-to-id.tab.keystream | Bin 0 -> 4096 bytes .../lookups/file-to-id.tab.keystream.len | Bin 0 -> 8 bytes .../caches-jvm/lookups/file-to-id.tab.len | Bin 0 -> 8 bytes .../lookups/file-to-id.tab.values.at | Bin 0 -> 91 bytes .../caches-jvm/lookups/file-to-id.tab_i | Bin 0 -> 32768 bytes .../caches-jvm/lookups/file-to-id.tab_i.len | Bin 0 -> 8 bytes .../caches-jvm/lookups/id-to-file.tab | Bin 0 -> 4096 bytes .../lookups/id-to-file.tab.keystream | Bin 0 -> 4096 bytes .../lookups/id-to-file.tab.keystream.len | Bin 0 -> 8 bytes .../caches-jvm/lookups/id-to-file.tab.len | Bin 0 -> 8 bytes .../lookups/id-to-file.tab.values.at | Bin 0 -> 478 bytes .../caches-jvm/lookups/id-to-file.tab_i | Bin 0 -> 32768 bytes .../caches-jvm/lookups/id-to-file.tab_i.len | Bin 0 -> 8 bytes .../cacheable/caches-jvm/lookups/lookups.tab | Bin 0 -> 4096 bytes .../caches-jvm/lookups/lookups.tab.keystream | Bin 0 -> 4096 bytes .../lookups/lookups.tab.keystream.len | Bin 0 -> 8 bytes .../caches-jvm/lookups/lookups.tab.len | Bin 0 -> 8 bytes .../caches-jvm/lookups/lookups.tab.values.at | Bin 0 -> 707 bytes .../caches-jvm/lookups/lookups.tab_i | Bin 0 -> 32768 bytes .../caches-jvm/lookups/lookups.tab_i.len | Bin 0 -> 8 bytes .../compileKotlin/cacheable/last-build.bin | Bin 0 -> 18 bytes .../shrunk-classpath-snapshot.bin | Bin 0 -> 1890 bytes .../local-state/build-history.bin | Bin 0 -> 31 bytes .../compileJava/previous-compilation-data.bin | Bin 0 -> 3266 bytes wikigame/build/tmp/jar/MANIFEST.MF | 2 + wikigame/completable-future/build.gradle.kts | 34 ++++ .../META-INF/completable-future.kotlin_module | Bin 0 -> 24 bytes .../caches-jvm/inputs/source-to-output.tab | Bin 0 -> 4096 bytes .../inputs/source-to-output.tab.keystream | Bin 0 -> 4096 bytes .../inputs/source-to-output.tab.keystream.len | Bin 0 -> 8 bytes .../inputs/source-to-output.tab.len | Bin 0 -> 8 bytes .../inputs/source-to-output.tab.values.at | Bin 0 -> 314 bytes .../caches-jvm/inputs/source-to-output.tab_i | Bin 0 -> 32768 bytes .../inputs/source-to-output.tab_i.len | Bin 0 -> 8 bytes .../jvm/kotlin/class-attributes.tab | Bin 0 -> 4096 bytes .../jvm/kotlin/class-attributes.tab.keystream | Bin 0 -> 4096 bytes .../kotlin/class-attributes.tab.keystream.len | Bin 0 -> 8 bytes .../jvm/kotlin/class-attributes.tab.len | Bin 0 -> 8 bytes .../jvm/kotlin/class-attributes.tab.values.at | Bin 0 -> 52 bytes .../jvm/kotlin/class-attributes.tab_i | Bin 0 -> 32768 bytes .../jvm/kotlin/class-attributes.tab_i.len | Bin 0 -> 8 bytes .../jvm/kotlin/class-fq-name-to-source.tab | Bin 0 -> 4096 bytes .../class-fq-name-to-source.tab.keystream | Bin 0 -> 4096 bytes .../class-fq-name-to-source.tab.keystream.len | Bin 0 -> 8 bytes .../kotlin/class-fq-name-to-source.tab.len | Bin 0 -> 8 bytes .../class-fq-name-to-source.tab.values.at | Bin 0 -> 110 bytes .../jvm/kotlin/class-fq-name-to-source.tab_i | Bin 0 -> 32768 bytes .../kotlin/class-fq-name-to-source.tab_i.len | Bin 0 -> 8 bytes .../jvm/kotlin/internal-name-to-source.tab | Bin 0 -> 4096 bytes .../internal-name-to-source.tab.keystream | Bin 0 -> 4096 bytes .../internal-name-to-source.tab.keystream.len | Bin 0 -> 8 bytes .../kotlin/internal-name-to-source.tab.len | Bin 0 -> 8 bytes .../internal-name-to-source.tab.values.at | Bin 0 -> 171 bytes .../jvm/kotlin/internal-name-to-source.tab_i | Bin 0 -> 32768 bytes .../kotlin/internal-name-to-source.tab_i.len | Bin 0 -> 8 bytes .../cacheable/caches-jvm/jvm/kotlin/proto.tab | Bin 0 -> 4096 bytes .../caches-jvm/jvm/kotlin/proto.tab.keystream | Bin 0 -> 4096 bytes .../jvm/kotlin/proto.tab.keystream.len | Bin 0 -> 8 bytes .../caches-jvm/jvm/kotlin/proto.tab.len | Bin 0 -> 8 bytes .../caches-jvm/jvm/kotlin/proto.tab.values.at | Bin 0 -> 263 bytes .../caches-jvm/jvm/kotlin/proto.tab_i | Bin 0 -> 32768 bytes .../caches-jvm/jvm/kotlin/proto.tab_i.len | Bin 0 -> 8 bytes .../jvm/kotlin/source-to-classes.tab | Bin 0 -> 4096 bytes .../kotlin/source-to-classes.tab.keystream | Bin 0 -> 4096 bytes .../source-to-classes.tab.keystream.len | Bin 0 -> 8 bytes .../jvm/kotlin/source-to-classes.tab.len | Bin 0 -> 8 bytes .../kotlin/source-to-classes.tab.values.at | Bin 0 -> 97 bytes .../jvm/kotlin/source-to-classes.tab_i | Bin 0 -> 32768 bytes .../jvm/kotlin/source-to-classes.tab_i.len | Bin 0 -> 8 bytes .../cacheable/caches-jvm/lookups/counters.tab | 2 + .../caches-jvm/lookups/file-to-id.tab | Bin 0 -> 4096 bytes .../lookups/file-to-id.tab.keystream | Bin 0 -> 4096 bytes .../lookups/file-to-id.tab.keystream.len | Bin 0 -> 8 bytes .../caches-jvm/lookups/file-to-id.tab.len | Bin 0 -> 8 bytes .../lookups/file-to-id.tab.values.at | Bin 0 -> 55 bytes .../caches-jvm/lookups/file-to-id.tab_i | Bin 0 -> 32768 bytes .../caches-jvm/lookups/file-to-id.tab_i.len | Bin 0 -> 8 bytes .../caches-jvm/lookups/id-to-file.tab | Bin 0 -> 4096 bytes .../lookups/id-to-file.tab.keystream | Bin 0 -> 4096 bytes .../lookups/id-to-file.tab.keystream.len | Bin 0 -> 8 bytes .../caches-jvm/lookups/id-to-file.tab.len | Bin 0 -> 8 bytes .../lookups/id-to-file.tab.values.at | Bin 0 -> 110 bytes .../caches-jvm/lookups/id-to-file.tab_i.len | Bin 0 -> 8 bytes .../cacheable/caches-jvm/lookups/lookups.tab | Bin 0 -> 4096 bytes .../caches-jvm/lookups/lookups.tab.keystream | Bin 0 -> 4096 bytes .../lookups/lookups.tab.keystream.len | Bin 0 -> 8 bytes .../caches-jvm/lookups/lookups.tab.len | Bin 0 -> 8 bytes .../caches-jvm/lookups/lookups.tab.values.at | Bin 0 -> 109 bytes .../caches-jvm/lookups/lookups.tab_i | Bin 0 -> 32768 bytes .../caches-jvm/lookups/lookups.tab_i.len | Bin 0 -> 8 bytes .../compileKotlin/cacheable/last-build.bin | Bin 0 -> 18 bytes .../shrunk-classpath-snapshot.bin | Bin 0 -> 692 bytes .../local-state/build-history.bin | Bin 0 -> 31 bytes .../compileJava/previous-compilation-data.bin | Bin 0 -> 23846 bytes .../src/main/java}/Main.java | 2 - .../src/main/java}/WikiGame.kt | 2 - .../src/main/java}/WikiGameFutureImpl.java | 8 +- .../main/java}/WikiGameFutureSimpleImpl.java | 7 +- .../src/main/java}/WikiGameSerialImpl.java | 6 +- .../coroutines}/build.gradle.kts | 30 +-- .../src/main/java}/coroutines/Main.kt | 6 +- .../java}/coroutines/repository/WikiGame.kt | 2 +- .../coroutines/repository/WikiGameDumbImpl.kt | 8 +- .../wiki/WikiRemoteDataSourceImpl.kt | 8 +- .../wiki/data/source/WikiRemoteDataSource.kt | 2 +- wikigame/executor/build.gradle.kts | 34 ++++ .../main/META-INF/executor.kotlin_module | Bin 0 -> 24 bytes .../caches-jvm/inputs/source-to-output.tab | Bin 0 -> 4096 bytes .../inputs/source-to-output.tab.keystream | Bin 0 -> 4096 bytes .../inputs/source-to-output.tab.keystream.len | Bin 0 -> 8 bytes .../inputs/source-to-output.tab.len | Bin 0 -> 8 bytes .../inputs/source-to-output.tab.values.at | Bin 0 -> 274 bytes .../caches-jvm/inputs/source-to-output.tab_i | Bin 0 -> 32768 bytes .../inputs/source-to-output.tab_i.len | Bin 0 -> 8 bytes .../jvm/kotlin/class-attributes.tab | Bin 0 -> 4096 bytes .../jvm/kotlin/class-attributes.tab.keystream | Bin 0 -> 4096 bytes .../kotlin/class-attributes.tab.keystream.len | Bin 0 -> 8 bytes .../jvm/kotlin/class-attributes.tab.len | Bin 0 -> 8 bytes .../jvm/kotlin/class-attributes.tab.values.at | Bin 0 -> 52 bytes .../jvm/kotlin/class-attributes.tab_i | Bin 0 -> 32768 bytes .../jvm/kotlin/class-attributes.tab_i.len | Bin 0 -> 8 bytes .../jvm/kotlin/class-fq-name-to-source.tab | Bin 0 -> 4096 bytes .../class-fq-name-to-source.tab.keystream | Bin 0 -> 4096 bytes .../class-fq-name-to-source.tab.keystream.len | Bin 0 -> 8 bytes .../kotlin/class-fq-name-to-source.tab.len | Bin 0 -> 8 bytes .../class-fq-name-to-source.tab.values.at | Bin 0 -> 100 bytes .../jvm/kotlin/class-fq-name-to-source.tab_i | Bin 0 -> 32768 bytes .../kotlin/class-fq-name-to-source.tab_i.len | Bin 0 -> 8 bytes .../jvm/kotlin/internal-name-to-source.tab | Bin 0 -> 4096 bytes .../internal-name-to-source.tab.keystream | Bin 0 -> 4096 bytes .../internal-name-to-source.tab.keystream.len | Bin 0 -> 8 bytes .../kotlin/internal-name-to-source.tab.len | Bin 0 -> 8 bytes .../internal-name-to-source.tab.values.at | Bin 0 -> 151 bytes .../jvm/kotlin/internal-name-to-source.tab_i | Bin 0 -> 32768 bytes .../kotlin/internal-name-to-source.tab_i.len | Bin 0 -> 8 bytes .../cacheable/caches-jvm/jvm/kotlin/proto.tab | Bin 0 -> 4096 bytes .../caches-jvm/jvm/kotlin/proto.tab.keystream | Bin 0 -> 4096 bytes .../jvm/kotlin/proto.tab.keystream.len | Bin 0 -> 8 bytes .../caches-jvm/jvm/kotlin/proto.tab.len | Bin 0 -> 8 bytes .../caches-jvm/jvm/kotlin/proto.tab.values.at | Bin 0 -> 253 bytes .../caches-jvm/jvm/kotlin/proto.tab_i | Bin 0 -> 32768 bytes .../caches-jvm/jvm/kotlin/proto.tab_i.len | Bin 0 -> 8 bytes .../jvm/kotlin/source-to-classes.tab | Bin 0 -> 4096 bytes .../kotlin/source-to-classes.tab.keystream | Bin 0 -> 4096 bytes .../source-to-classes.tab.keystream.len | Bin 0 -> 8 bytes .../jvm/kotlin/source-to-classes.tab.len | Bin 0 -> 8 bytes .../kotlin/source-to-classes.tab.values.at | Bin 0 -> 97 bytes .../jvm/kotlin/source-to-classes.tab_i | Bin 0 -> 32768 bytes .../jvm/kotlin/source-to-classes.tab_i.len | Bin 0 -> 8 bytes .../cacheable/caches-jvm/lookups/counters.tab | 2 + .../caches-jvm/lookups/file-to-id.tab | Bin 0 -> 4096 bytes .../lookups/file-to-id.tab.keystream | Bin 0 -> 4096 bytes .../lookups/file-to-id.tab.keystream.len | Bin 0 -> 8 bytes .../caches-jvm/lookups/file-to-id.tab.len | Bin 0 -> 8 bytes .../lookups/file-to-id.tab.values.at | Bin 0 -> 55 bytes .../caches-jvm/lookups/file-to-id.tab_i | Bin 0 -> 32768 bytes .../caches-jvm/lookups/file-to-id.tab_i.len | Bin 0 -> 8 bytes .../caches-jvm/lookups/id-to-file.tab | Bin 0 -> 4096 bytes .../lookups/id-to-file.tab.keystream | Bin 0 -> 4096 bytes .../lookups/id-to-file.tab.keystream.len | Bin 0 -> 8 bytes .../caches-jvm/lookups/id-to-file.tab.len | Bin 0 -> 8 bytes .../lookups/id-to-file.tab.values.at | Bin 0 -> 100 bytes .../caches-jvm/lookups/id-to-file.tab_i.len | Bin 0 -> 8 bytes .../cacheable/caches-jvm/lookups/lookups.tab | Bin 0 -> 4096 bytes .../caches-jvm/lookups/lookups.tab.keystream | Bin 0 -> 4096 bytes .../lookups/lookups.tab.keystream.len | Bin 0 -> 8 bytes .../caches-jvm/lookups/lookups.tab.len | Bin 0 -> 8 bytes .../caches-jvm/lookups/lookups.tab.values.at | Bin 0 -> 109 bytes .../caches-jvm/lookups/lookups.tab_i | Bin 0 -> 32768 bytes .../caches-jvm/lookups/lookups.tab_i.len | Bin 0 -> 8 bytes .../compileKotlin/cacheable/last-build.bin | Bin 0 -> 18 bytes .../shrunk-classpath-snapshot.bin | Bin 0 -> 692 bytes .../local-state/build-history.bin | Bin 0 -> 31 bytes .../compileJava/previous-compilation-data.bin | Bin 0 -> 23848 bytes .../executor/src/main/java}/Main.java | 2 - .../executor/src/main/java}/WikiGame.kt | 2 - .../src/main/java}/WikiGameExecutorImpl.java | 6 +- .../src/main/java}/WikiGameSerialImpl.java | 6 +- .../gradle/wrapper/gradle-wrapper.properties | 1 + {wiki-game-coroutines => wikigame}/gradlew | 6 - .../gradlew.bat | 180 +++++++++--------- wikigame/settings.gradle.kts | 7 + .../src/main/java/point/rar}/Main.java | 2 +- .../src/main/java/point/rar}/model/Link.kt | 2 +- .../src/main/java/point/rar}/model/Page.kt | 2 +- .../main/java/point/rar}/model/PageLinks.kt | 2 +- .../java/point/rar}/model/QueryBacklinks.kt | 4 +- .../main/java/point/rar}/model/QueryLinks.kt | 2 +- .../point/rar}/model/WikiBacklinksResponse.kt | 4 +- .../point/rar}/model/WikiLinksResponse.kt | 2 +- 271 files changed, 241 insertions(+), 536 deletions(-) delete mode 100644 wiki-game-common/pom.xml delete mode 100644 wiki-game-completable-feature/pom.xml delete mode 100644 wiki-game-coroutines/.gitignore delete mode 100644 wiki-game-coroutines/settings.gradle.kts delete mode 100644 wiki-game-executor/.gitignore delete mode 100644 wiki-game-executor/pom.xml create mode 100644 wikigame/.gradle/7.6/checksums/checksums.lock create mode 100644 wikigame/.gradle/7.6/dependencies-accessors/dependencies-accessors.lock create mode 100644 wikigame/.gradle/7.6/dependencies-accessors/gc.properties create mode 100644 wikigame/.gradle/7.6/executionHistory/executionHistory.bin create mode 100644 wikigame/.gradle/7.6/executionHistory/executionHistory.lock create mode 100644 wikigame/.gradle/7.6/fileChanges/last-build.bin create mode 100644 wikigame/.gradle/7.6/fileHashes/fileHashes.bin create mode 100644 wikigame/.gradle/7.6/fileHashes/fileHashes.lock create mode 100644 wikigame/.gradle/7.6/fileHashes/resourceHashesCache.bin create mode 100644 wikigame/.gradle/7.6/gc.properties create mode 100644 wikigame/.gradle/buildOutputCleanup/buildOutputCleanup.lock create mode 100644 wikigame/.gradle/buildOutputCleanup/cache.properties create mode 100644 wikigame/.gradle/buildOutputCleanup/outputFiles.bin create mode 100644 wikigame/.gradle/file-system.probe create mode 100644 wikigame/.gradle/vcs-1/gc.properties create mode 100644 wikigame/build.gradle.kts create mode 100644 wikigame/build/classes/kotlin/main/META-INF/wikigame.kotlin_module create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i.len create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i.len create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream.len create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.len create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream.len create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.len create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i.len create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream.len create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.len create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.values.at create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i.len create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/counters.tab create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i.len create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.len create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab_i create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab_i.len create mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/last-build.bin create mode 100644 wikigame/build/kotlin/compileKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin create mode 100644 wikigame/build/kotlin/compileKotlin/local-state/build-history.bin create mode 100644 wikigame/build/tmp/compileJava/previous-compilation-data.bin create mode 100644 wikigame/build/tmp/jar/MANIFEST.MF create mode 100644 wikigame/completable-future/build.gradle.kts create mode 100644 wikigame/completable-future/build/classes/kotlin/main/META-INF/completable-future.kotlin_module create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i.len create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i.len create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream.len create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.len create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/counters.tab create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i.len create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.len create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab_i create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab_i.len create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/last-build.bin create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin create mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/local-state/build-history.bin create mode 100644 wikigame/completable-future/build/tmp/compileJava/previous-compilation-data.bin rename {wiki-game-completable-feature/src/main/java/point/rar/feature => wikigame/completable-future/src/main/java}/Main.java (94%) rename {wiki-game-completable-feature/src/main/java/point/rar/feature => wikigame/completable-future/src/main/java}/WikiGame.kt (80%) rename {wiki-game-completable-feature/src/main/java/point/rar/feature => wikigame/completable-future/src/main/java}/WikiGameFutureImpl.java (95%) rename {wiki-game-completable-feature/src/main/java/point/rar/feature => wikigame/completable-future/src/main/java}/WikiGameFutureSimpleImpl.java (95%) rename {wiki-game-executor/src/main/java/point/rar/feature => wikigame/completable-future/src/main/java}/WikiGameSerialImpl.java (94%) rename {wiki-game-coroutines => wikigame/coroutines}/build.gradle.kts (53%) rename {wiki-game-coroutines/src/main/java/point/rar => wikigame/coroutines/src/main/java}/coroutines/Main.kt (69%) rename {wiki-game-coroutines/src/main/java/point/rar => wikigame/coroutines/src/main/java}/coroutines/repository/WikiGame.kt (74%) rename {wiki-game-coroutines/src/main/java/point/rar => wikigame/coroutines/src/main/java}/coroutines/repository/WikiGameDumbImpl.kt (93%) rename {wiki-game-coroutines/src/main/java/point/rar => wikigame/coroutines/src/main/java}/coroutines/wiki/WikiRemoteDataSourceImpl.kt (91%) rename {wiki-game-coroutines/src/main/java/point/rar => wikigame/coroutines/src/main/java}/coroutines/wiki/data/source/WikiRemoteDataSource.kt (77%) create mode 100644 wikigame/executor/build.gradle.kts create mode 100644 wikigame/executor/build/classes/kotlin/main/META-INF/executor.kotlin_module create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i.len create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i.len create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream.len create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.len create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/counters.tab create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i.len create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.len create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab_i create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab_i.len create mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/last-build.bin create mode 100644 wikigame/executor/build/kotlin/compileKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin create mode 100644 wikigame/executor/build/kotlin/compileKotlin/local-state/build-history.bin create mode 100644 wikigame/executor/build/tmp/compileJava/previous-compilation-data.bin rename {wiki-game-executor/src/main/java/point/rar/feature => wikigame/executor/src/main/java}/Main.java (94%) rename {wiki-game-executor/src/main/java/point/rar/feature => wikigame/executor/src/main/java}/WikiGame.kt (80%) rename {wiki-game-executor/src/main/java/point/rar/feature => wikigame/executor/src/main/java}/WikiGameExecutorImpl.java (96%) rename {wiki-game-completable-feature/src/main/java/point/rar/feature => wikigame/executor/src/main/java}/WikiGameSerialImpl.java (94%) rename {wiki-game-coroutines => wikigame}/gradle/wrapper/gradle-wrapper.properties (86%) rename {wiki-game-coroutines => wikigame}/gradlew (98%) rename {wiki-game-coroutines => wikigame}/gradlew.bat (89%) create mode 100644 wikigame/settings.gradle.kts rename {wiki-game-common/src/main/java/point/rar/common => wikigame/src/main/java/point/rar}/Main.java (81%) rename {wiki-game-common/src/main/java/point/rar/common/wiki/domain => wikigame/src/main/java/point/rar}/model/Link.kt (70%) rename {wiki-game-common/src/main/java/point/rar/common/wiki/domain => wikigame/src/main/java/point/rar}/model/Page.kt (80%) rename {wiki-game-common/src/main/java/point/rar/common/wiki/domain => wikigame/src/main/java/point/rar}/model/PageLinks.kt (74%) rename {wiki-game-common/src/main/java/point/rar/common/wiki/domain => wikigame/src/main/java/point/rar}/model/QueryBacklinks.kt (54%) rename {wiki-game-common/src/main/java/point/rar/common/wiki/domain => wikigame/src/main/java/point/rar}/model/QueryLinks.kt (75%) rename {wiki-game-common/src/main/java/point/rar/common/wiki/domain => wikigame/src/main/java/point/rar}/model/WikiBacklinksResponse.kt (55%) rename {wiki-game-common/src/main/java/point/rar/common/wiki/domain => wikigame/src/main/java/point/rar}/model/WikiLinksResponse.kt (76%) diff --git a/wiki-game-common/pom.xml b/wiki-game-common/pom.xml deleted file mode 100644 index 3d91cd0..0000000 --- a/wiki-game-common/pom.xml +++ /dev/null @@ -1,109 +0,0 @@ - - - 4.0.0 - - point.rar.common - wiki-game-common - 2.0 - jar - - 19 - 19 - 1.9.0 - - - - - org.asynchttpclient - async-http-client - 3.0.0.Beta1 - - - io.github.resilience4j - resilience4j-ratelimiter - 2.1.0 - - - io.github.resilience4j - resilience4j-timelimiter - 2.1.0 - - - com.fasterxml.jackson.core - jackson-core - 2.15.2 - - - org.jetbrains.kotlinx - kotlinx-serialization-core-jvm - 1.2.2 - - - - - - - - org.jetbrains.kotlin - kotlin-maven-plugin - ${kotlin.version} - - - compile - process-sources - - compile - - - - test-compile - test-compile - - test-compile - - - - - ${maven.compiler.target} - - - - org.apache.maven.plugins - maven-compiler-plugin - - - compile - compile - - compile - - - - testCompile - test-compile - - testCompile - - - - - - org.apache.maven.plugins - maven-jar-plugin - - - - true - libs/ - - point.rar.common.Main - - - - - - - - \ No newline at end of file diff --git a/wiki-game-completable-feature/pom.xml b/wiki-game-completable-feature/pom.xml deleted file mode 100644 index b7ce12b..0000000 --- a/wiki-game-completable-feature/pom.xml +++ /dev/null @@ -1,99 +0,0 @@ - - - 4.0.0 - - point.rar - wiki-game-common - 1.0-SNAPSHOT - - - wiki-game-completable-feature - - - 19 - 19 - UTF-8 - 1.9.0 - - - - - org.jetbrains.kotlin - kotlin-stdlib-jdk8 - ${kotlin.version} - - - org.jetbrains.kotlin - kotlin-test - ${kotlin.version} - test - - - com.fasterxml.jackson.dataformat - jackson-dataformat-xml - 2.14.2 - - - org.apache.httpcomponents - httpclient - 4.5.13 - - - point.rar.common - wiki-game-common - 2.0 - - - - - - - org.jetbrains.kotlin - kotlin-maven-plugin - ${kotlin.version} - - - compile - process-sources - - compile - - - - test-compile - test-compile - - test-compile - - - - - ${maven.compiler.target} - - - - org.apache.maven.plugins - maven-compiler-plugin - - - compile - compile - - compile - - - - testCompile - test-compile - - testCompile - - - - - - - - \ No newline at end of file diff --git a/wiki-game-coroutines/.gitignore b/wiki-game-coroutines/.gitignore deleted file mode 100644 index 5b2e2bb..0000000 --- a/wiki-game-coroutines/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -.gradle* -build* \ No newline at end of file diff --git a/wiki-game-coroutines/settings.gradle.kts b/wiki-game-coroutines/settings.gradle.kts deleted file mode 100644 index 18f01dd..0000000 --- a/wiki-game-coroutines/settings.gradle.kts +++ /dev/null @@ -1,2 +0,0 @@ -rootProject.name = "wiki-game-coroutines" - diff --git a/wiki-game-executor/.gitignore b/wiki-game-executor/.gitignore deleted file mode 100644 index 5ff6309..0000000 --- a/wiki-game-executor/.gitignore +++ /dev/null @@ -1,38 +0,0 @@ -target/ -!.mvn/wrapper/maven-wrapper.jar -!**/src/main/**/target/ -!**/src/test/**/target/ - -### IntelliJ IDEA ### -.idea/modules.xml -.idea/jarRepositories.xml -.idea/compiler.xml -.idea/libraries/ -*.iws -*.iml -*.ipr - -### Eclipse ### -.apt_generated -.classpath -.factorypath -.project -.settings -.springBeans -.sts4-cache - -### NetBeans ### -/nbproject/private/ -/nbbuild/ -/dist/ -/nbdist/ -/.nb-gradle/ -build/ -!**/src/main/**/build/ -!**/src/test/**/build/ - -### VS Code ### -.vscode/ - -### Mac OS ### -.DS_Store \ No newline at end of file diff --git a/wiki-game-executor/pom.xml b/wiki-game-executor/pom.xml deleted file mode 100644 index 51346da..0000000 --- a/wiki-game-executor/pom.xml +++ /dev/null @@ -1,110 +0,0 @@ - - - 4.0.0 - - point.rar - wiki-game-common - 1.0-SNAPSHOT - - - wiki-game-execotor - - - 19 - 19 - UTF-8 - 1.9.0 - - - - - org.jetbrains.kotlin - kotlin-stdlib-jdk8 - ${kotlin.version} - - - org.jetbrains.kotlin - kotlin-test - ${kotlin.version} - test - - - com.fasterxml.jackson.dataformat - jackson-dataformat-xml - 2.14.2 - - - org.apache.httpcomponents - httpclient - 4.5.13 - - - io.github.resilience4j - resilience4j-timelimiter - 2.1.0 - - - point.rar.common - wiki-game-common - 2.0 - - - - - - - org.jetbrains.kotlin - kotlin-maven-plugin - ${kotlin.version} - - - compile - process-sources - - compile - - - - test-compile - test-compile - - test-compile - - - - - ${maven.compiler.target} - - - - org.apache.maven.plugins - maven-compiler-plugin - - - - --enable-preview - - - - - compile - compile - - compile - - - - testCompile - test-compile - - testCompile - - - - - - - - \ No newline at end of file diff --git a/wikigame/.gradle/7.6/checksums/checksums.lock b/wikigame/.gradle/7.6/checksums/checksums.lock new file mode 100644 index 0000000000000000000000000000000000000000..1e52391c353b4648b2a5d8e062c9d5a22ce3120a GIT binary patch literal 17 ScmZS1NZgy1rY&vH00jUh5dz-; literal 0 HcmV?d00001 diff --git a/wikigame/.gradle/7.6/dependencies-accessors/dependencies-accessors.lock b/wikigame/.gradle/7.6/dependencies-accessors/dependencies-accessors.lock new file mode 100644 index 0000000000000000000000000000000000000000..9af0f7bb955708eb565113fef24a861a0502694c GIT binary patch literal 17 ScmZR!6yLEfwI!IH0SW*m_yYX^ literal 0 HcmV?d00001 diff --git a/wikigame/.gradle/7.6/dependencies-accessors/gc.properties b/wikigame/.gradle/7.6/dependencies-accessors/gc.properties new file mode 100644 index 0000000..e69de29 diff --git a/wikigame/.gradle/7.6/executionHistory/executionHistory.bin b/wikigame/.gradle/7.6/executionHistory/executionHistory.bin new file mode 100644 index 0000000000000000000000000000000000000000..c0090ef71fe691d5143fcafe11fc89ed410df17d GIT binary patch literal 109951 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 literal 0 HcmV?d00001 diff --git a/wikigame/.gradle/7.6/executionHistory/executionHistory.lock b/wikigame/.gradle/7.6/executionHistory/executionHistory.lock new file mode 100644 index 0000000000000000000000000000000000000000..530e9a49fed3877bbe333dd4b6436d5e63c3bcd7 GIT binary patch literal 17 TcmZQptX1)v6EGu$0RqGUBOC(% literal 0 HcmV?d00001 diff --git a/wikigame/.gradle/7.6/fileChanges/last-build.bin b/wikigame/.gradle/7.6/fileChanges/last-build.bin new file mode 100644 index 0000000000000000000000000000000000000000..f76dd238ade08917e6712764a16a22005a50573d GIT binary patch literal 1 IcmZPo000310RR91 literal 0 HcmV?d00001 diff --git a/wikigame/.gradle/7.6/fileHashes/fileHashes.bin b/wikigame/.gradle/7.6/fileHashes/fileHashes.bin new file mode 100644 index 0000000000000000000000000000000000000000..bff2d22859b2dfdeab633034f01e94d770590497 GIT binary patch literal 31797 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 literal 0 HcmV?d00001 diff --git a/wikigame/.gradle/7.6/fileHashes/fileHashes.lock b/wikigame/.gradle/7.6/fileHashes/fileHashes.lock new file mode 100644 index 0000000000000000000000000000000000000000..6bf83d91a0ab7aab1323f713652ab5ddd3de58c3 GIT binary patch literal 17 VcmZSfdZOf?cHit30~jz`0RS-$1VaD- literal 0 HcmV?d00001 diff --git a/wikigame/.gradle/7.6/fileHashes/resourceHashesCache.bin b/wikigame/.gradle/7.6/fileHashes/resourceHashesCache.bin new file mode 100644 index 0000000000000000000000000000000000000000..fe0eda905f91f054e4d47de4387b687636589e5f GIT binary patch literal 19857 zcmeI(`#02i9LMoVag^&UgUBssYbqj28CuL%=R3ooIw4|0=(4+#R4!4*rI_SWwvcO~ zHn-yxLXKpuPAcshJ46?9ZMBt@MXfpC?`J#f<1gsEzvm3!^YA*~bG}dGC*RpbqiHCA zrViSdgYo4Q&Y%DkfC5ke3P1rU00p1`6o3Ly017|>C;$bZ02F`%Pyh-*fv=^&j+q-- zMBa>sp_JrA=_rk6B0qD&jB|H9Jf1eyOa7Sah5mnV=7|i0$4avy-R{PJ{?_%wE*K?y-{D-7-t&!hO6Dn1^EbS(pQ;EE> zrX;Lg`2=-e_9u}yy_U^W*v8&V?YAO-KqN7&I)$q!7bE}kw5T}9JTI1Xdp`0`XN$0N zy%83q+c_eC_Of;N)H;;|q!T{K`-NtG8EI{9)IJdTU}}9e$IWzrbgnk?VR1$!E&m9I z@@C{pi%bfN1`CELzw)1Va#CYWk7oVXO=U#GLg zpK@d5yjSVYw9MoQ(z!#(o%^H9uSoCPNjlMje3$*&$l|yO5$Sdl$UQ7S8;XpgOi^|A5i;L3O-4#E~W`c9+Gr`nMV_zDG} z02F`%Pyh-*0Vn_kpa2wr0#E=7KmjNK1)u;FfC5ke3P1rU00p1`6o3Ly017|>C;$bZ z02F`%Pyh-*0Vn_kpupE%z-;FB7SFusl9#f4ueDU}yHvxa4IcLr?wm`XL7o3EUX3_^ z!{@dwi0G+NRGU(hJbyfE(S7^=C)%~)d+CPS$*s{uFuusl>p7&;!tJ9gv0AyoPW|{| z3H!WM`F8`Z4evkNgg&~w3tuoTIjP3RGGc?ZsdtR_c-_Yr2aJelZgo-y?`Hv+m_o%J9P6?to`mX@eo0BPN0P!qlt7J@&Wd6N*Nf z8zSYCZsCgwkxkXgV)`IIY2bzNi<}&M(H61F$luN(Nu94(#Ryl7!xz4jLv_i!&7XT# zs8{e0osGg5i)DZ1zNJ-$fs+1?5igxkZ=Rse zhpXiK z^Jn!)j7)fCQ#P&=Cwo1TEt4;UFS;&oH9WheecD#rS5Rvz$i^2PYGu;lAyOgD0`*c` zOY=Dvue-+l>s>6ZvNC??5D6mm@oN-0gt|1{&i>3~xQ72MUA6&V+?5U7=3Tvm%dBS& zdT!fcj4wPLlY1U!dgoeqtd@&*Iy8+hxUpI7l|D|1J8!wMRq{ROc#rjo<*hbr_lXpy z|MK@+r(B3%P`h}B?>tE8=&haj+ci*lyFUIfba#cgEm0|CS@N1+Gnia~b zj^+)Fj0msA=f~iSgPwbe>yL5t3lH~NY%N_N#1}CRVjr4@FY5`9X~PSund5ic^X;W5 l+Wt^8_vWg=6SWCV_%;6KK93p`youSYdosQ~L@7YB_!oKgSjqqZ literal 0 HcmV?d00001 diff --git a/wikigame/.gradle/7.6/gc.properties b/wikigame/.gradle/7.6/gc.properties new file mode 100644 index 0000000..e69de29 diff --git a/wikigame/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/wikigame/.gradle/buildOutputCleanup/buildOutputCleanup.lock new file mode 100644 index 0000000000000000000000000000000000000000..f81f048e3794d5e650a61782d6aac70fad8dd060 GIT binary patch literal 17 UcmZR6wC+HT<^sD93=j|k06dNb3jhEB literal 0 HcmV?d00001 diff --git a/wikigame/.gradle/buildOutputCleanup/cache.properties b/wikigame/.gradle/buildOutputCleanup/cache.properties new file mode 100644 index 0000000..971117e --- /dev/null +++ b/wikigame/.gradle/buildOutputCleanup/cache.properties @@ -0,0 +1,2 @@ +#Sat Sep 02 19:45:30 MSK 2023 +gradle.version=7.6 diff --git a/wikigame/.gradle/buildOutputCleanup/outputFiles.bin b/wikigame/.gradle/buildOutputCleanup/outputFiles.bin new file mode 100644 index 0000000000000000000000000000000000000000..40ae3641f1f9fd8d9237b8370eaf272ad697043b GIT binary patch literal 19919 zcmeI%eNfYN9Ki7*>H?Mo2VzKYC&<&lNFXBuDuD z5)WaZl*mKaL6Rvd7z!Myz=e1`OTd|OiOk~|jr)E-^Sb@BTW9BWpWSWjUi*B%zy01D zzklY%Vy$^;k=|HOZ~9N4;xjCO1+V}XzyeqR3t#~(fCaDs7Qg~n01IFNEPw^D02aUk zSm6Isz+ZMEn&f2G*eqLmqMgKI*>Pk~d_GkdJ80)hd&$efarpfp%f~!lcQUPrxL_A} zwl7yu*mv z=}xv|Q-4wJ)4fL}h0S!H2?HJi{I5mVt8&Bo|&G(vyyT8%v22J_UP$vh(f|7n%6y;Da=3O(*D`1zs6 z_hyZQuTbv>|K;|Rj($^vS>l3u@T;~ap{HC^Vg4d`%NGX@ybwOnPv={}Z9( zum0m?mQ|BAabXR3Z=lYl<@0rJ#F;$sKHv5r@uA{m;=F9|I~<-}p-sgE^(gScufq&W z-VLGO2L^a?*fL>DwQm@o%<~K2g|VxbwLh$JFeWZK1Aedal<8__k^W!sUk0D37#hx& zytR?e+k#K+P2YO_#$$Ej%pLIQwRRR=2IDStUPJE1rEC|^{4P501b#nbQGBf^U_Ei+ zXW%pDb<5_e*<9lM8SqD}!~Kt@*GcJowA|aGJ)~2u2dR64Klx2_b6Uy(y$&#Yz!z#4 z3a#2dr=JVI34HNxd1h<$pCe=+K`!`8;dQ@!{@V=oAaKrDmW!Dw07ElGn2Xx_&OKOH`OvDrin8R z;AW17o^1l>89L7fw~jj=sCMKWy^aaCf!lb0#o^eNr_=dC@HfVmtNW!`RS*|l0C&9o$)Dw;`bXoux~)>?SA!cQ4VZ)~d;a>+NB14;>F_q}g~UnHTxWy;?gY zY%!;bINt?)+jcL#gR}KFiSv@cz1`=o74+;{NnCgfd`ETofcd621LA^u@ZiM#9>XgJ z={};h;1Nk|UyCHa>vW%H@b`x+qqyUzf2I5AfJa@niw*7xo~LdKzIU>zyK$^Ui#Tr- zJnr5|UEvDdEyS60@OX{%Xo>q^2629d-1i%9GVba9ow(=(ctUd(FQ-##LtI!4zAwhh zW;Djql{oJk@MQbbf`O)^7wG=q%l$#@h_{z3{Tu~-;Hlpo^Ll6*Q%dF;eQ@~8VzKG9 ziA>-l7Qg~n01IFNEPw^D02aUkSO5!P0W5$8umBdo0$2bGU;!+E1+V}XzyeqR3t#~( zfCaDs7Qg~n01IFNEPw_6O#yq^Vh!0{ZRx)Bu<9QogXdgSd(Voi6h-mem6=gorHrVy y^Rru}+Rmz->3?~wXZH@D|Fcl-+?83S%#3P%6jv#V;?b3vQCy{rsJ64xtNsQg9UFlF literal 0 HcmV?d00001 diff --git a/wikigame/.gradle/file-system.probe b/wikigame/.gradle/file-system.probe new file mode 100644 index 0000000000000000000000000000000000000000..596c735e6607c4f7d6753d0f8c36cc5ef786307a GIT binary patch literal 8 PcmZQzVC)Jzof!xK2b=|Nqwj8mjy2|NlfF{pAP5JwT~ZFd71*Aut*OqaiRF f0;3@?8UmvsFd71*Aut*OqaiRF0;3^7LtWw9r zZhN{EdzDcP4RvfB-TBGXd*cQQ9H{eG-BSI~;Z+)EDv#}S`wUqzxCtoGYkYE009U<00Izz00bZa0SG|g G9|CUyF_B0B literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len new file mode 100644 index 0000000000000000000000000000000000000000..6fdc033695a244e08b264dbc888a15302bbc4d12 GIT binary patch literal 8 McmZQz00GAN005}~p#T5? literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len new file mode 100644 index 0000000000000000000000000000000000000000..817b326d9eb94f6a38f5e047201a69ab944ef476 GIT binary patch literal 8 LcmZQz0D~O>0Kfpb literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at new file mode 100644 index 0000000000000000000000000000000000000000..b8981a08af11cb362c2ddea544d5d4b2ed3c985d GIT binary patch literal 2131 zcmcJQO-_SA7=~v-@4&R8-}_bC;-x70LF56|l>NBuDtNkn4E< z=4v(#!i$CP;QNBI7)OjK1qvr3XO!cVl#fhMo?}TQPDKn1Zwru5OUe^9u3z{2gPf^I zGs3Ch4Kgr*bQDNR7<~rWKrg#OSF_;!Y_Xo>N1D(hNnzaR2+R2k1}|vRmDE<}mFmrg z`LOiUR6A_aEOiH}5bfoyd%*@<+uI0jbdz0|hfrU<4=NK}{Veg;7_aT{V2(VP(DxDA z^@%wlQNpSkIhA^6l-U*=nxzjW_tQe1`|7`zsjs#9xVO3^S8Y{u+7h+b{zn{4-0KKw Zw^{vX`#sCX-d@+8i2;1tUO!009C72oNAZ zfB=D9fm=*>+3=P7X-I$o0RjXF5FkK+009C72oNApTHqKL_Pz0<^dScb5FkK+009C7 P2oNAZfB*pkH4*p&^<)l! literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i.len new file mode 100644 index 0000000000000000000000000000000000000000..131e265740f37d77b7c4a3676d2a7704ca3e4a29 GIT binary patch literal 8 McmZQz0D%Su009U9fdBvi literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab new file mode 100644 index 0000000000000000000000000000000000000000..43b5a468129b08a13bd75dba30f1ecb9c28144bf GIT binary patch literal 4096 zcmeIu(FVd$9LMp0JwPI*7wEo=UZDG~qPw184>3g#5hEg+h!K%ujEFdIvR7Drk2>tC z2gvWw_BlIeHonQ^+A^l&Z(-V>MZaOTVEJPFPW>H@%wJ*r+2H$7-w)@%bbP02n$?cjw#;I;RQ=PV~?MnaEuww@rX-2V2XQmxWfv!IBc42aEb}WxJEv!Q2`ZD X0ToaI6;J^cPyrQC0TobzzbWtr6H`@d literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream new file mode 100644 index 0000000000000000000000000000000000000000..b5e10556d60a58c712a8bd65009ef6412b1572fc GIT binary patch literal 4096 zcmeH@!4APd5QaTOFC2s@5n{zFaCN}NdBa2|ZFiep4m`cI3A@^@iu1q6nSbY-`J!C2 zx(XwW$n=>~v1OI?Lq)OCSuPc8H3+t2ONM324>D0Tu#*?+hKdEvjv70TId0B);M(H* z8=3oBo|3cxO{+sb+m1GC33|w0Fk0RfH@6&W@+IV9YWE*G;rC$&vbk24mepawl!LE+ t%X@naLqE!EUpvfO6OO-V&wA_*9t^+$48Q;kzyJ)u01UtY48XwO2A<+s1B3to literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len new file mode 100644 index 0000000000000000000000000000000000000000..88a2818c6f8d6e122f8031e84de5972d8268029a GIT binary patch literal 8 McmZQz00E{o006iEuK)l5 literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len new file mode 100644 index 0000000000000000000000000000000000000000..14f7c061cc4bef2fdb72d8ebd5cc8c9a23a22d1b GIT binary patch literal 8 McmZQz00Bk`001HY8UO$Q literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at new file mode 100644 index 0000000000000000000000000000000000000000..c1f99d4026680e243c9b16ea568dda619bca65f9 GIT binary patch literal 106 zcmdOA@JLNeNi9+cN=?o$N>OmjFH#6dEh^3|E=kQR@klJr@J%cTOUx-v4KB$qN=#2> JWMCi<0RXKe5*Gjf literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i new file mode 100644 index 0000000000000000000000000000000000000000..edbb2cf419ac44d71414bf7d0103f26bd1b6654b GIT binary patch literal 32768 zcmeI%KPZG@90%}MN=8MLC=-LhKsMVYqYZ&6kP~ zHjn@T0x1_bihKv9{r8l|6psJ_0+kbp?|myz&C`_|Xc7Se1PBlyK!5-N0t5&UAVA

E_nzLAV7cs0RjXFWJ%yH%D#^t zA5^>ZSsXAs{B>3BbId0|fB*pk1PBlyK!5-N0%;Ohi!k}uiJLTKN@JGG2sN4CUrJ*( znFtUdK;ZuZ*D<0n-nH=mNhS~=K!5-N0t5&UsJ=icju;#$d{+M?C)9#KK0-EKbQk}c z^)WUc&Mcn)b-#TCvLvt@WxMyL{9c}=m#!-T0t5&UAn;4zBko4-a=pJ6-4G}v@Eq%X zJN>I=9$O|*Qv%zOcKr0Jy{1A7OMpNo1dgL+=g{(8Cdw*FfIwXe+(xUOwvCgzET~v1OI?Lq)OCSuPc8H3+t2ONM324>D0Tu#*?+hKdEvjv70TId0B);M(H* z8=3oBo|3cxO{+sb+m1GC33|w0Fk0RfH@6&W@+IV9YWE*G;rC$&vbk24mepawl!LE+ t%X@naLqE!EUpvfO6OO-V&wA_*9t^+$48Q;kzyJ)u01UtY48XwO2A<+s1B3to literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len new file mode 100644 index 0000000000000000000000000000000000000000..88a2818c6f8d6e122f8031e84de5972d8268029a GIT binary patch literal 8 McmZQz00E{o006iEuK)l5 literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len new file mode 100644 index 0000000000000000000000000000000000000000..14f7c061cc4bef2fdb72d8ebd5cc8c9a23a22d1b GIT binary patch literal 8 McmZQz00Bk`001HY8UO$Q literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at new file mode 100644 index 0000000000000000000000000000000000000000..816b5e3d3362b61d665cdcac30cd86c0d62d3edb GIT binary patch literal 1228 zcmd6l%?g4*5P7Z_ zq~Qd_3zcHdH$rB;%ygKF>Zsb#V?&#+hHBb$Yv_cHZG`s~(sK?;mVd0<=10u4_Wy3Y kEjD1jjq_P#;&6kP~ zHjn@T0x1_bihKv9{r8l|6psJ_0+kbp?|myz&C`_|Xc7Se1PBlyK!5-N0t5&UAVA

E_nzLAV7cs0RjXFWJ%yH%D#^t zA5^>ZSsXAs{B>3BbId0|fB*pk1PBlyK!5-N0%;Ohi!k}uiJLTKN@JGG2sN4CUrJ*( znFtUdK;ZuZ*D<0n-nH=mNhS~=K!5-N0t5&UsJ=icju;#$d{+M?C)9#KK0-EKbQk}c z^)WUc&Mcn)b-#TCvLvt@WxMyL{9c}=m#!-T0t5&UAn;4zBko4-a=pJ6-4G}v@Eq%X zJN>I=9$O|*Qv%zOcKr0Jy{1A7OMpNo1dgL+=g{(8Cdw*FfIwXe+(xUOwvCgzET}0!+`-9fB_hQ0T_S*7=Qs7fB_iz+rSG_MFT|u literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len new file mode 100644 index 0000000000000000000000000000000000000000..88a2818c6f8d6e122f8031e84de5972d8268029a GIT binary patch literal 8 McmZQz00E{o006iEuK)l5 literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len new file mode 100644 index 0000000000000000000000000000000000000000..14f7c061cc4bef2fdb72d8ebd5cc8c9a23a22d1b GIT binary patch literal 8 McmZQz00Bk`001HY8UO$Q literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at new file mode 100644 index 0000000000000000000000000000000000000000..816b5e3d3362b61d665cdcac30cd86c0d62d3edb GIT binary patch literal 1228 zcmd6l%?g4*5P7Z_ zq~Qd_3zcHdH$rB;%ygKF>Zsb#V?&#+hHBb$Yv_cHZG`s~(sK?;mVd0<=10u4_Wy3Y kEjD1jjq_P#;B+qSXC4uKV2Sbbj9V`=04^x=C$Pk@yiHK!5-N0t5&UD3ZWO^gN7?wHB#PO`Zj& zB5&^PzBA9UB_DSl8#FF&45YQlRuoSk&W@zjua^LU^aXBXg!bO~#`GsK0RaM!L2%LC zvP6PFAq8F{eDU(8uaF(G2@oJafWS`zr*UDkbFlfR>&};!z<7*X)zGw4T2q^rKzR!6 z#@Y=XU8#MCE>Cq^6Cm(ipeB9YP;`NVXk6WEc`kafLIMN`5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0tDhu(n)gNJ5r5;009EI3S33N)A8^`t~s73K%jgDW@7d1 z{(H831#JEw1y*9I&${~U|G1l-2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5Fk)W F0$+YlGCBYN literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len new file mode 100644 index 0000000000000000000000000000000000000000..131e265740f37d77b7c4a3676d2a7704ca3e4a29 GIT binary patch literal 8 McmZQz0D%Su009U9fdBvi literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab new file mode 100644 index 0000000000000000000000000000000000000000..c691266213b4bd9024ef1107f872a2a5c8d8989a GIT binary patch literal 4096 zcmeH@F$+Oa7={m%Nd}aO&B$P3v&djlHk(2D5u*GHf8Y*wga2@+8-p?^MY*|=B=UMs z+`5xpy>FfKob!F>-qU%etwqu>X*-2UeHMk7F(WR)*h=&aTgHwswpaabqV=%F+;pLg3U6d8~K8IS=PkO3Kx0U3}18IS=P_-6xe D3dU2| literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream new file mode 100644 index 0000000000000000000000000000000000000000..788ff54259ae7dbb3ffd11084a593ac263111658 GIT binary patch literal 4096 zcmeH_y$*sf6h?glCl(!yMl?pFjjy1qgSt4HMsG~h(vlVieR_dJTA}qB-M$ zYl~k}(C-6%aFK&n)l2@zmbUH)I>@m%TJ#EAMy1SUOUS|0`rjC5Ww9%mSV;qNrl?y6&$uZMSaiN;?>7D>NYrLh8l{rISWG1`;ojNlj~-#hvYL zY=6M`5BLLk)tCGYAZ;%|yh42i5)!=OC4#*|NPM3=+esQH4V|khqLrGvoPB5C-S@fA z^W3G#N~W=CI#cUr*>*OkZrIM$Ez@x=*E6eL$#A!C8oPIl%AUF5*^aSg{+MI}AiX!2nw9rEZnbnMzqc5c=$<;xv7g@Fx-cfpzKw%#W z`KKw+|UkU&=F^^v`x4I(?VBx}P+8PXA?qe$~e$4XBV>jS}~(bqys zQMK&8Jb|H@WFu?4wpI0tj^PyV+M8yjxMo#%mT|4eHO=ZGWjxEPn8=)SO~*1S)+58S z?CLeU>Uz#z8AE&1aCS_Gy}7nydljqtd9mTfBHA~ds!=I!w5`9)-k*DC?K9)PQLGr% zt>T8~Sk zG$yvUjUFr85ZN^h8&f=6yf0H9IF@J5Y?zf#abwD*RJQlL-93*jw&;vmE!&&uZ1EaB z(nbBZsKj)ZnJUKey6KkLD=n&T;-X{iVkTUFjOlh!vdpqG!F1q_GxP+biuq&818c|H zGVYq+B=Mq*y)hD+MId@EeC2U6&q(eoX+#KpKa$6R*D=A6X@_=vO$P0Uh zbq7{0DNiMIQuL{=tI5^8rWA6zqRTp3Sx^@;us#}u?CJnFVF`9d_S;8RIi~d^tD%St zRYyvuDdE!kkTAhl?|gWGB>;Yc=(uZM|()O~>%e%}z#5 z%t1{y$5d7?EU2b5b`@q6y#myp6eUotylqwL-kS`pBT>xG&41M5i4Ee(;`#p4W3u!n zXaUn=b1kZd#&})axXd!O+E6*a-bww?hI{T4glY!&cbcTi{+RU*uAg+M_4({kkoE`$ zflyGL@)*SNwaH+H&Aefx$Q~$Ch1{}`9l?c_zLdZT5@(V)lLb-;PK>^s=SmgO;p|#c zIiUO-2tXPt4gf$oUP~7MB0XmXfQER(koKTYJ-mhB3zQAy@MeP|Ma%5V!|3!#gel(w zn>lg<(x|(JgLRk6*^3dYchfS%Tfn+Pio8{;n};F~o0fRkQHy_u7JoE!+r~Tlt9?BX zYWbxmIIu`Age%q0y)^lWt2e^smS$ggAydKH)ZmHG>c#z&*8a$(@JA*lSLW;dkv`0f z%GYVx_e#=yG8OKGKu8*&^txNLkfrPSJZeKo!p*zpUBWIO77q`)Mfj6>4 z%SkJIoVZJ~5x6vao<+Wu>&4*E4EiQfYtwgU_y{mPaA#`QkL%2^E_7$UkIkLA)LLe7 z_%v-*94;4scC%x1DQflQDviOrX*+&rE>0&d%89u+zX-^^bo!7R)N|m8@a$y~eya#z zdTT|5w=o}YeH@74-SNY1wDDzx!&Ha1<`C+=J=1x(Vw86{%o_NX`6MX*e=sfw_bwcX z|2yXnV&mN9CeAf#E)Liot?Q6@|8z6)E*~ad<50$cy`x9+jD4rdzP|+fRWZxIB2IjuJc`X-`RDeg@+P_bth`vw&CvG#%D zi3fk{4Z$A{BVvgC^!nJ3n)E|I+SYK{Ktt$9mya9yb>BAj53%uZwvE!_U}1YDha7y? z%^aMK(xk%`n z@ygM%j01}usXs*Gx801yD^W;nu=5yj*wJ{Nq3~2uc!B$Md3=(!Ch(u(CHT0=F7xca DXifwk literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i new file mode 100644 index 0000000000000000000000000000000000000000..9037815edbe77417c578dc7b9d793456a7a8c9be GIT binary patch literal 32768 zcmeI&F-RL>6bJANEgwQ{y%ZO*&fTOG1i?kAgOnx&3Z)bZf({}M zQbD_vYN4Q$79B(!q?D@Ap>NC*5=gu==6BO^-*@l--fucSE_s}EB`yL42oNAZfB*pk zDGA&}&e_Y^;gsUUv{+z1>b?1MI@;p0ZC`FbCg?AJn#^jD)d*hrvNV%bzFYzXvKKgs z7M>QD`?K#v2LuS52f>f=p?4$*+@-)(6o32k_}N`%s7-(X0RjYS34D!(&!ba=wbngv zFM(Il?xVuMdV6)PTLPUaun}VyM#eHbhwe;uQxhOiEzp}wlIbTOo>xC}-?+fX*qSTv z>^1&|odgIFAVA>$33SKzz^}RA6Zfw(9T6ZvfB=E!1y-U&<=de1^5!X3AdtGib|k*v z9J)+BSRerc1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009E=lXQ|C6=!--5FkLHS%JeS zaIyR1b+dK6Pk=z@3M|IxrLDiE&J{5ELlmgQP`7>gwTC#HnFtUdK!89!fqa}h{X6)6 iU2mUt0t5&UAV7cs0RjXF5FkK+009C72oNBUhQNPYIW^}1 literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len new file mode 100644 index 0000000000000000000000000000000000000000..131e265740f37d77b7c4a3676d2a7704ca3e4a29 GIT binary patch literal 8 McmZQz0D%Su009U9fdBvi literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab new file mode 100644 index 0000000000000000000000000000000000000000..f12eff4a8d8b5c6d4950d185183b802ccabc8bec GIT binary patch literal 4096 zcmbR3vzw0r2-rac39ha-|Gy8UJ%O|&(9ny2|NoBz(iT7(C_D;ALtr!nMnhmU1V%$(Gz3ON ZU^E0qLtr!nMnhmU1V%$(Gz5qY0RU+CA}as@ literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream new file mode 100644 index 0000000000000000000000000000000000000000..944b47d9e97d4e1c405c86b53f35d3722f762dc2 GIT binary patch literal 4096 zcmeIuF$=;l5QbrYOlNQCqJtn>2Su<3!BLJH5Cqze9fTTyX6aQw2r_mL;hO0(On zmWNZZHW{T@QN!Zt%6FzVi0>$Jq$ZqgO(6eXDUaghJ8NuegHOY+=h`E$^`8SHJP1Gl0uX=z1Rwwb2tWV=5P-lx1fE%t Bkw^dl literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len new file mode 100644 index 0000000000000000000000000000000000000000..6fdc033695a244e08b264dbc888a15302bbc4d12 GIT binary patch literal 8 McmZQz00GAN005}~p#T5? literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len new file mode 100644 index 0000000000000000000000000000000000000000..817b326d9eb94f6a38f5e047201a69ab944ef476 GIT binary patch literal 8 LcmZQz0D~O>0Kfpb literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at new file mode 100644 index 0000000000000000000000000000000000000000..6aa951d304187bc60045a32931f2c1062a031507 GIT binary patch literal 852 zcma)(&q~8U5XScjJbBTBM2sSeF1~_-^q^2H=&=mVpu=u=!pug{qgNlm*EKEJV6xkI z&G*~y&%~MuLWNSyaKTa)w=BgJMM)!uI01dVhx!S8gO8B~Ua&H|HB*RIKwKjw&6WW&0gPkMXmbiQC8_%9p{;R zwNEqH`p}@fU&F$+1Du}rUH{5m{MiVY@9<{!lW*6{%PrF8hn#GI^10t;aI$A|w3$9b ltvM*#zI&4DE^+lgK40w19HuPR_xLS!K1y_jF2>n>nIDx4Ksx{c literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i new file mode 100644 index 0000000000000000000000000000000000000000..c2a36863843540ff5acb91b328645eaf1c76c55f GIT binary patch literal 32768 zcmeIuy9okO5CzbO3Pyrm_({Y}P{G{T5^TZPXfYH_3=IvfKrBG4z#6Q8i2;1tUO!009C72oNAZ zfB=D9fqP7M+3=P7X-I$o0RjXF5FkK+009C72oNApTHqEJ_Pz0<^dScb5FkK+009C7 P2oNAZfB*pkH4*p&MYIlp literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len new file mode 100644 index 0000000000000000000000000000000000000000..131e265740f37d77b7c4a3676d2a7704ca3e4a29 GIT binary patch literal 8 McmZQz0D%Su009U9fdBvi literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab new file mode 100644 index 0000000000000000000000000000000000000000..fc0fd9ba773dbf5648ffd93e403d258651abb91c GIT binary patch literal 4096 zcmbR3vzw0r2$(K-}3cXWp>2a*In&q^aAjWi7;_ vkfAOU0;z>{{yMUMFEY0M(A34zaTK5c1t>rP3Q&Lo6rcbFC_n)U{8``ug!mf} literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream.len new file mode 100644 index 0000000000000000000000000000000000000000..1ddb457a113791d5e7198fe8d8fbbeeccd3514d3 GIT binary patch literal 8 LcmZQz00UP508Ic! literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.len new file mode 100644 index 0000000000000000000000000000000000000000..01bdaa1da7d937c7e7d98e54ba912f88ab95c7f2 GIT binary patch literal 8 LcmZQz0D}nt0GI%g literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at new file mode 100644 index 0000000000000000000000000000000000000000..7d49eac2136224b567093089a933ff4543a07249 GIT binary patch literal 324 zcmZwCF$%&!5QX7@SI~Y7wGdqK3Ko(=Ax6-8Fb^HF?uMC7p*OeFSV&mYfA42zmF1uc zVoF?sRAw8*6cA;N@G&R7?WsADYjKQ0=!(}UGfiM0t&rGzsNn35eQl=-VRHP0%u-N% xh8@zrTBPdGLLM8s)Gnp-LHbu*r|ir%|AHm730~2^VL7z;c8ByN8>hbe>fhUf t*IXh%fB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oTsnU;t~M1)~4} literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i.len new file mode 100644 index 0000000000000000000000000000000000000000..131e265740f37d77b7c4a3676d2a7704ca3e4a29 GIT binary patch literal 8 McmZQz0D%Su009U9fdBvi literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab new file mode 100644 index 0000000000000000000000000000000000000000..c2c27d0ab7d6de173c8a8774b84e1b0b6b9a0e22 GIT binary patch literal 4096 zcmbR3vzw0r2-rac3QRZa l(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S``90swtOW;Xx; literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream.len new file mode 100644 index 0000000000000000000000000000000000000000..3a3075b1c7bfe5be9724a142e408d7022e61c988 GIT binary patch literal 8 McmZQz00Blm000;O5C8xG literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.len new file mode 100644 index 0000000000000000000000000000000000000000..817b326d9eb94f6a38f5e047201a69ab944ef476 GIT binary patch literal 8 LcmZQz0D~O>0Kfpb literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.values.at b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.values.at new file mode 100644 index 0000000000000000000000000000000000000000..2b792d5392ce648c1c6b5fc25f152586bae734b6 GIT binary patch literal 387 zcmd6g!3hFE5Ck^`jbI~KK|>JqK7x2~|JG}CaGg13M-Zd;p%L86cTrWV)Da^+pLj7J z^UgdU=}lTtqeHtLFb$|r_F;}IH)(yhsG_gZ=z=P5gqRl5pet(GQ|Snf{g2a^Y4MfH Q)*cfa=Q=Mm>;C7`2Z{@m!~g&Q literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i new file mode 100644 index 0000000000000000000000000000000000000000..816f809778fa3573f6164b16d8abd446b7afc807 GIT binary patch literal 32768 zcmeIuAr1mD6a>&F2rfWyBq$Jg9BvPQ#d8jVgaiQ&91>9I^=Je~;20Rb+ygYtZt|*{ zikaz4{nSei0RjXF5FkK+Kz4y=BvzlpH+!%^0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C81dh?Mp8x6sRVoM&AV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV8o+0=w8Ux~yI;nq&$A0t5&UAV8p~ zz%AMq?`l%CR9R;QuCaW2nr%A!0mBJ21h#QsKI&oP$&~;B0t5&UAV464z&SF;gZ({2 Nln4R@2oNYJ@CT~65aR#< literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i.len new file mode 100644 index 0000000000000000000000000000000000000000..131e265740f37d77b7c4a3676d2a7704ca3e4a29 GIT binary patch literal 8 McmZQz0D%Su009U9fdBvi literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/counters.tab b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/counters.tab new file mode 100644 index 0000000..3d952e7 --- /dev/null +++ b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/counters.tab @@ -0,0 +1,2 @@ +7 +0 \ No newline at end of file diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab new file mode 100644 index 0000000000000000000000000000000000000000..60f72c74f664645961544e8dd5a6820321a40f5f GIT binary patch literal 4096 zcmbR3vzw0r2-rac3n`#^ddkd_1*x&cVX0qIph8YnypMnhmU1V%$(Gz3ONU^E0qLtr!n WMnhmU1V%$(Gz3ONU^E1X3;_TDtRut# literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream new file mode 100644 index 0000000000000000000000000000000000000000..944b47d9e97d4e1c405c86b53f35d3722f762dc2 GIT binary patch literal 4096 zcmeIuF$=;l5QbrYOlNQCqJtn>2Su<3!BLJH5Cqze9fTTyX6aQw2r_mL;hO0(On zmWNZZHW{T@QN!Zt%6FzVi0>$Jq$ZqgO(6eXDUaghJ8NuegHOY+=h`E$^`8SHJP1Gl0uX=z1Rwwb2tWV=5P-lx1fE%t Bkw^dl literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len new file mode 100644 index 0000000000000000000000000000000000000000..6fdc033695a244e08b264dbc888a15302bbc4d12 GIT binary patch literal 8 McmZQz00GAN005}~p#T5? literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len new file mode 100644 index 0000000000000000000000000000000000000000..817b326d9eb94f6a38f5e047201a69ab944ef476 GIT binary patch literal 8 LcmZQz0D~O>0Kfpb literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at new file mode 100644 index 0000000000000000000000000000000000000000..25454f32baadef9abd2a46657e796ddb67161bb6 GIT binary patch literal 91 zcmdOA@JLNeNi9+cN=?o$N>OmjFH#6dEh^3|E=kQR@klJr@J%cTOUx-v4KB$qN=#2> XVE_Rz$p|Kyz$7!6WC4?`V3G|0pe7PE literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i new file mode 100644 index 0000000000000000000000000000000000000000..c2a36863843540ff5acb91b328645eaf1c76c55f GIT binary patch literal 32768 zcmeIuy9okO5CzbO3Pyrm_({Y}P{G{T5^TZPXfYH_3=IvfKrBG4z#6Q8i2;1tUO!009C72oNAZ zfB=D9fqP7M+3=P7X-I$o0RjXF5FkK+009C72oNApTHqEJ_Pz0<^dScb5FkK+009C7 P2oNAZfB*pkH4*p&MYIlp literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i.len new file mode 100644 index 0000000000000000000000000000000000000000..131e265740f37d77b7c4a3676d2a7704ca3e4a29 GIT binary patch literal 8 McmZQz0D%Su009U9fdBvi literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab new file mode 100644 index 0000000000000000000000000000000000000000..1850b55bc3186fce03d867afefe3a3a53bf94b4e GIT binary patch literal 4096 zcmeH@%L#xm5C#2v5X3HQ#wx@@EJLsa8xZWlHtfPUizavy3wRHb*=&9=bGOwIDQ)s; z?qUTa!x8Je&&0GDAq7?StbBhAyWhpm`*vr73G87CTbRM)bS{Srw0{N&6d8~K8IS=P UkO3Kx0U3}18IS=Pkb$2DE+S_kcmMzZ literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream new file mode 100644 index 0000000000000000000000000000000000000000..2459ed687d441aba38ffb9935e376d2ba65878a1 GIT binary patch literal 4096 tcmeIu0TBQ|1OPDn(?7BvZi}$UdcP+yV8DO@0|pEjFkrxd0Rsl^4lG}^02TlM literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len new file mode 100644 index 0000000000000000000000000000000000000000..379d85ced69049230006887a8ba1241e30c6e7df GIT binary patch literal 8 LcmZQz00VXa01p5N literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len new file mode 100644 index 0000000000000000000000000000000000000000..817b326d9eb94f6a38f5e047201a69ab944ef476 GIT binary patch literal 8 LcmZQz0D~O>0Kfpb literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at new file mode 100644 index 0000000000000000000000000000000000000000..c4d33bceaf3443f1a598733983539d21825dcf4f GIT binary patch literal 478 zcmb8qO%8%E5QgC%g#~N7(1n<2`~ibTBUYnJGl7ZLLQAH_#M=u-joTjJ`Q91MQiK92 z5SSY(f~BD#L$cC3)Gh^k+d_SUvcZEh1Xmoeewc~fI$0bq@k)f;QqC)on&068yf#uh zPC&de1(tjxwdyJ7sj@cIs)!AJTAk{8wxts`_M!U*={bj7l^;K1k+=W06Bhf}vsChz U7HDguZTJ0*O?_wH7yM1U0CO9p>Hq)$ literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i new file mode 100644 index 0000000000000000000000000000000000000000..0667ccd230691e805561eaf82040d187c95dd0f2 GIT binary patch literal 32768 zcmeIuD-M7_5JbV@w`X68T)7g-5osJ}Al1oBMvSUzwbf@m_ma-Erjg!e#{d8T literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len new file mode 100644 index 0000000000000000000000000000000000000000..131e265740f37d77b7c4a3676d2a7704ca3e4a29 GIT binary patch literal 8 McmZQz0D%Su009U9fdBvi literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab new file mode 100644 index 0000000000000000000000000000000000000000..6d7383f0f08dab88b6e74788c3ee4abb221369c0 GIT binary patch literal 4096 zcmeIvO-K}B9Khi>D>aMNLr5Q&g+eb25rlY%0wLIg2*o0{3t=51N+K#OBtpbPh+zbM zTS$a;h=Q`{140bSL+(K&A}BftffqZ7f_-eyQVX6scXq zP0gQ!w&fvoJ1m&um8JJAb6(s^Q(SxU_hjky()z#5d;U5%jB^XexQox2 z`dH6y?qC;Nd6Fl1n3vej$86;U)0}4$H?H)(Y-9s7Oz|k|c%Df<!w)>iNj~H|zULcORE99hM!sN{BkbV=-sL^! zd7FzIWNK9imzm=Q_Op+p?ByKKa#K|ZrK>&16 literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream new file mode 100644 index 0000000000000000000000000000000000000000..99d0341fe91fcb43884b1f46a469e22d380f0f3b GIT binary patch literal 4096 zcmeHJO>fjN5Vb^E*lqbJq6au2AwWVx3jcwM0}@4rA|Z}uu@*O3J0$L^@au8xI3C-R z;BZ6Q-a2pQ&GUR^30Zx-V$HAjT$C+YUeX;cDk?UFEZMeJ+TN#othSQ4wHj8y)$*zmmS?y@U<-1o)E>zLbrr65wtm?Ng zHS3WUB|+_a<5Rnt^VEEBPB#p3Uv_qTRMMck=H$Gg>r&qdeRfh0Si=-`HzGw&zVMO{ z#GhDO>rKG)9e0jK--HtwtTdJHS&A*V*vS&h>!d%7`c#;95C=cO;KCePVa}PktqF-~ z2C+RE0bPa>_@?4Y-|!LC4$Y%jobNTUmvYJj6m`nYrg}D-3KqjA&GQB6^8$`GOuaoj z|NPZ_17^ewpU=D)`{1PU(W>+X&T-T0{W30J$d=Y{Mu0g8kI@8n?+Lg8lYVX_C!PGd zO}ZIX&&O54Cj)(%5l(5QyVsl#R7~ zBKRG6ibaPfocN08c)K#>_(CPG{;CAN!E2fq7YxHcgu0oS7wT#OmjFH#6dEh^3|E=kQR@klJr@J%cTOUx-v4KB$qN=#2> zVE_U)Fv-LLVuP3vJ|kEZnPlSusQ>{+AZEd;3&Sk1sZ2oi%xLCgs05ogz@ic$-+=(w z#XuV5C{`dw2@`lYAp8Ypfqei87e=_hS->o2kU5ADfSZ5_NmhdX2RjDhBnISoL1r_7 bO(C9S2CK&;A-*7wgoG8uKghmEmA&2CYv=PrdjB?6psiH0r3;4L|uEj zEH_E~nNo&A5NN@Al|MP6N{Cn#gF68Q?lzBZStsY(Lyo#|@@*@PBUfN#=Trg(s3X2x zOBOiQX)k96%fK&V^d}J@0s<3gN4#kru@Qk-pGx-J&21Fnl_xJagcK@)~xdJE5%Ppm4s4w+d z5nlG}sGT2yT8x9)_<9^aFOK&%V_ZwyCw_OlC-smbfm+NLFO{0=fJ6pA1$Aj`asThV zD=;tKjo86?-&7*_C`}?j1c-ps2xP&NUwq?Xr#WQAkrMlwUdlK1Ldyxny7f7@d!x{C zDIO8vL%@RjGE36j1U^2fulo>KgF2YzcP*G=WlYgCp)$YltEs&=~OM-DoGs? zAOemMSdIIVbBXrfdpqKbY{f$$1?zXrpGoM!!O%OOTbpI39b#m2LiF$EAnBIGH<;B&m3G+JdX{w&9J=sZ{fD-fN>&MXNTq(4` zKKty!BChtV*hOPMVqZfdt+T8Qh)8v4aD5DK(Dm6buS33@PHYGiY1)!aD-Gk_q1P%U z3xEA!G}g$kLi1G2v`ty)tHjmgA<*i5&>Zegrn|+rKZ>Ljhch|-e;o}v3&iw zs(&5wY;8Vs%~k%%FA*RDM1XYyTGVNu^WDm0!Hw(H|=^hU6>zm;)`P=vzR=?r!BQLqI+j>mj!VoZmySLsHB}_CIM#1mW zrd)}d>cR-*nn40O%-t3=HY_6{)a#To)crc z`@Z-7PZv?0Qeu9s8+Cy9et@W;P%?H2XnX#@&XE|={f@jHb>K=@eS+P@>4aMoFk*b0 Ps_4D9TMr_MXP&@cIw0dS literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab_i.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab_i.len new file mode 100644 index 0000000000000000000000000000000000000000..131e265740f37d77b7c4a3676d2a7704ca3e4a29 GIT binary patch literal 8 McmZQz0D%Su009U9fdBvi literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/last-build.bin b/wikigame/build/kotlin/compileKotlin/cacheable/last-build.bin new file mode 100644 index 0000000000000000000000000000000000000000..0791d768e94d2f02f3af305cc50525f4085dcb08 GIT binary patch literal 18 YcmZ4UmVvdLhk=2yE9`X6Q3fCY05;MD{{R30 literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin b/wikigame/build/kotlin/compileKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin new file mode 100644 index 0000000000000000000000000000000000000000..1a06c20dd221968fd7ee2e1b2d0d6910f5f30680 GIT binary patch literal 1890 zcmb_cyKWOv5IqoQ{fBoeKB@66npGiT1d09K&C>o~#$Q^Xiyj8k-wB0|Dl=xk^F zopLv!7ieLB$=hRGgwBWk%E$QT7v;Rn?+RY?-~R2f@5U1Qfn@;q>yMdSw%GBGtG_K1GXQ@WQ*at{AR zuWM9RNR%luh5GyUw}(H{PY=Gc5bpA;d782~*>Xi?wmOju)o`BOl+h$s;XmSue!;U! zhJ?c6TIcj-Ss6u10F6Iwt*GrkbECIXLZJD^&P?OZeG|5%R VNmi{j-}$d><_nx}kGdQo`2*fPNY(%V literal 0 HcmV?d00001 diff --git a/wikigame/build/kotlin/compileKotlin/local-state/build-history.bin b/wikigame/build/kotlin/compileKotlin/local-state/build-history.bin new file mode 100644 index 0000000000000000000000000000000000000000..d8328c4e8542f8592206d22df66e4087a40d44d7 GIT binary patch literal 31 ccmZ4UmVvcgk^ur385kJ5!cONLh4L8~0AfJ}4FCWD literal 0 HcmV?d00001 diff --git a/wikigame/build/tmp/compileJava/previous-compilation-data.bin b/wikigame/build/tmp/compileJava/previous-compilation-data.bin new file mode 100644 index 0000000000000000000000000000000000000000..73117b8441d3d46d8898f38ed33d54f6c747cc26 GIT binary patch literal 3266 zcmb7H3se(V8ot*Oc_?^=QqZovMA-E)Mz99O*u{hj#6Zmiu%g5v8N!6gOvp?Ku)ZJ( zZ($|9$tKfj|w35yUH?(!w*G=mnfs$|?cnBY~4*IONyh>e}mQ9TPRN`ZDRhvIT%O z;D0_pTukvMeF$H|4^$QMBFk{2fYVfLmW&3~qLtB$`4-fF?!t|-u9OZ-(}?gJB~Hp; z6OiUJ1~`h%2vpK~-fBR9sPj2da@Y4m{Y4pnKt@Y#hnwr-zqojQRS7Y1A=0S9bB3m?h8O;Pk+ueaU@rmw;k5t>LM zitwEXYVcaoR*qsN(V&*L(3D8!vGgQR!*e2DH`g{y52w7Roh)y?+`g;9)}E`-2F^u+t2R?*!nV)Fhx=l6<)3}4OioUI zi&#MTrC=p+HnSi}1x`GsfhrEmhZfK&dvx2GGc)SH1K8%M&vOpBbK7QerF!e zJ9N{&Ta$aICp}Ii(*v|v^ky18OBhl9+LEK{xVV4b@FjKEGL>2Lv(-V1fzu|4?|=$= z38>}uHZv}eHXudt+_2-$r(uqWeL>`ApVFL#OQYqIWxz!j(=0l6HssERf$uM;)qV7& zOByE6)dWSOO_HPAMjweaychU4{R7m0T&G&Dp@=-fZ=ytxNe?aV9Q47h84nJg9vKMQ z{vtnHHa^~vM3ec+QX{A@v0x<+rl;5fP$?Q%ToZ0PgSJL`Wqkbg#oHHUd4FH8@%@)+ zVWCpWf;!q_rS(IyUxwmSHr?wTG4l({ltYs)ouB7rCj2;1B@9JDj=zS_Jvm`@NcXZp z^HmNUmvZ_7E6*`ycs05! z>37cT9GI!HnG=d^tGk4SA{k%<^)Ic5T~dtoWzI8DXwBNLN5bU`9f!AaUNh4M`s^7c z+ESv7_zkfFIC-maC8#ygVxAQnN>~Nzf7}8D$!g%F1#u0;I$=vuv!h#oa{k@KgQ0Pk zy4M_TDTnD5@a+Hx1XYy2kTTL*bhV_>bfEoV)Ioda&6C~X4kuK&pt=$gRgkELL=7ZX z)WR3GW?9Bm2Z4*FIO8fwJ^n`-8GQr9g5v~{!m92axB7Y6k}y}w%FeqneMdicL&aK{ zo$)TthlR%5L=7Sv_8;%>tozO$;E=4p#S`nGVm*x3NhYDZYubm7(4%+HO1@w4jk_$n z5t7mkIJnJ%nYXY&T5a1GA;S#o;Nzh|ZjNb;r)+Z%)(yz8Yu#^oVwfH|P|2n^jLoSYI9q5kE>M zBDR=fZFFoz0VPD}3vg>`gTKd!u@Jx}2tvUjGjFi5^fZRc=Og(1h}i$0GQ_Ymh8R3y zhNYbFbCH7w&@f~;PQ4C-7(6He;W6`gj}bBm0^;R{aD`6rSGK@%i2Lt`AQ6J`@iKXm zDl^w0l*2|$stIm{-u{G|)bT}b*o+_C4S^gJHGm|K(<(475hx*$ez(-7JW_WZPHh!=bBux|4n zrz-LoA$W|idyFWD9z&d-L$EA8^**+er;tX^Ax#j1kRi9c^vX{-WuxbDu`oSl--4-N z4Y%SUa;#jz3$olM7;n&-63elLa~h%A+rJqbm&6v1Ny3IFRGFCB4*a}itiqIoo!Ex6 z{$B|bgS+}L9e4a3h-?^S_aIRve$jyVMFZ}I#79v5F`V8Br@!JQ8M$xpc%X`@!8!cJ GpZ@?4aI1X) literal 0 HcmV?d00001 diff --git a/wikigame/build/tmp/jar/MANIFEST.MF b/wikigame/build/tmp/jar/MANIFEST.MF new file mode 100644 index 0000000..58630c0 --- /dev/null +++ b/wikigame/build/tmp/jar/MANIFEST.MF @@ -0,0 +1,2 @@ +Manifest-Version: 1.0 + diff --git a/wikigame/completable-future/build.gradle.kts b/wikigame/completable-future/build.gradle.kts new file mode 100644 index 0000000..c8e56f3 --- /dev/null +++ b/wikigame/completable-future/build.gradle.kts @@ -0,0 +1,34 @@ +plugins { + id("java") + kotlin("jvm") version "1.9.10" +} + +group = "point.rar" +version = "1.0-SNAPSHOT" + +repositories { + mavenCentral() +} + +dependencies { + implementation(project(mapOf("path" to ":"))) + testImplementation(platform("org.junit:junit-bom:5.9.1")) + testImplementation("org.junit.jupiter:junit-jupiter") + + val kotlinVersion = "1.9.10" + implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion") + implementation("org.jetbrains.kotlin:kotlin-test:$kotlinVersion") + + implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.14.2") + implementation("org.apache.httpcomponents:httpclient:4.5.13") + implementation("io.github.resilience4j:resilience4j-timelimiter:2.1.0") + implementation("io.github.resilience4j:resilience4j-ratelimiter:2.1.0") +} + +tasks.test { + useJUnitPlatform() +} + +tasks.withType { + options.compilerArgs.add("--enable-preview") +} \ No newline at end of file diff --git a/wikigame/completable-future/build/classes/kotlin/main/META-INF/completable-future.kotlin_module b/wikigame/completable-future/build/classes/kotlin/main/META-INF/completable-future.kotlin_module new file mode 100644 index 0000000000000000000000000000000000000000..1e9f2ca4d180a083a06174d407c30581ce729120 GIT binary patch literal 24 YcmZQzU|?ooU|eSnEDq8~2%LkOPe|RU{AdV_hQMeD jjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kgRc_9D*#r_JH literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream new file mode 100644 index 0000000000000000000000000000000000000000..d5abc42a57ab711d3c4ec3c4836d9376b2099e10 GIT binary patch literal 4096 zcmeIuK@LDL5Cu?&>6Y2sBEp7<#8O5xl4^@o>-^3k`R@p?RO2-CO*OA|H!0GWznw(h xoaB3oDF{75lV@|%!7tNdtZCUxVPgguzyJm?fB_6(00S7n00uCC0Sx?O-~(=K6ukfd literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len new file mode 100644 index 0000000000000000000000000000000000000000..130ab288134144812e637e1779d150d9a83c3d73 GIT binary patch literal 8 LcmZQz00V0P07C#g literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len new file mode 100644 index 0000000000000000000000000000000000000000..2a17e6e5bd9e7704741c2a3ae485eb2d2e302b87 GIT binary patch literal 8 LcmZQz0D}$y0FVHQ literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at new file mode 100644 index 0000000000000000000000000000000000000000..40858a77024e3490543fcd88da7b4d218d3426cc GIT binary patch literal 314 zcmb`CI}UvC=wRTmkl3!rB6PygO}R!q*|-QB~hA*{SJLUPo-uY9(~g6UL)=-XQC} zB*6v(YtgbeSnEDq8~2%LkOPe|RU{AdV_hQMeD jjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kgRc_9D*#r_JH literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream new file mode 100644 index 0000000000000000000000000000000000000000..bfcae2c8e2f3c522c3d0bbb9af7b5723c44b0000 GIT binary patch literal 4096 zcmeIuF%1A93;;0BIYR>X4vuA+{}&&mmC!iVwR7&mfB^#r3>YwAz<>b*1`HVZb>IPI C1p^lV literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len new file mode 100644 index 0000000000000000000000000000000000000000..9a6f654a2b1fe7f7cba4b266715a7a764968b486 GIT binary patch literal 8 LcmZQz00T|{01*HR literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len new file mode 100644 index 0000000000000000000000000000000000000000..2a17e6e5bd9e7704741c2a3ae485eb2d2e302b87 GIT binary patch literal 8 LcmZQz0D}$y0FVHQ literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at new file mode 100644 index 0000000000000000000000000000000000000000..53b2d29f95c6af74266544729b594570fda94d3b GIT binary patch literal 52 zcmdOA@JLNeNi9+cN=?o$N>OmjFH#6dEh^3|E=kQR@klJr@J%cTOUx-v4KB$qN=#2> HWMBXQ-PsZa literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i new file mode 100644 index 0000000000000000000000000000000000000000..0ea07a00c729455d91a6698c991502c763529461 GIT binary patch literal 32768 zcmeIuK@9*P5CpL$SmwtEVW>d~$heS>f=ScTBLV~n5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAW%$Ty`MA3F1BTd009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk c1PBlyK!5-N0t5&UAV7cs0RjXF5cpW&0s|le5&!@I literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i.len b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i.len new file mode 100644 index 0000000000000000000000000000000000000000..131e265740f37d77b7c4a3676d2a7704ca3e4a29 GIT binary patch literal 8 McmZQz0D%Su009U9fdBvi literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab new file mode 100644 index 0000000000000000000000000000000000000000..bdf584a84b58bf0b45e9b3a4c946653433feaad2 GIT binary patch literal 4096 zcmbR3vzw0r2pB;G3eSnEDq8~2%LkOPe|RU{AdV_hQMeD jjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kgRc_9D*#r_JH literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream new file mode 100644 index 0000000000000000000000000000000000000000..bfcae2c8e2f3c522c3d0bbb9af7b5723c44b0000 GIT binary patch literal 4096 zcmeIuF%1A93;;0BIYR>X4vuA+{}&&mmC!iVwR7&mfB^#r3>YwAz<>b*1`HVZb>IPI C1p^lV literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len new file mode 100644 index 0000000000000000000000000000000000000000..9a6f654a2b1fe7f7cba4b266715a7a764968b486 GIT binary patch literal 8 LcmZQz00T|{01*HR literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len new file mode 100644 index 0000000000000000000000000000000000000000..2a17e6e5bd9e7704741c2a3ae485eb2d2e302b87 GIT binary patch literal 8 LcmZQz0D}$y0FVHQ literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at new file mode 100644 index 0000000000000000000000000000000000000000..70664de958749a7f1e42d441d66c9618b1cf1ff4 GIT binary patch literal 110 zcmV~$%MOAt5Cu>^r3A~DbK&LAq2Q`Xctlfe>fUze{r2|Uoor1m#U()b6|j02Edt8oD6*gF%Ri=vpZt*{ H)|37LQ?Dlb literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i new file mode 100644 index 0000000000000000000000000000000000000000..0ea07a00c729455d91a6698c991502c763529461 GIT binary patch literal 32768 zcmeIuK@9*P5CpL$SmwtEVW>d~$heS>f=ScTBLV~n5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAW%$Ty`MA3F1BTd009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk c1PBlyK!5-N0t5&UAV7cs0RjXF5cpW&0s|le5&!@I literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len new file mode 100644 index 0000000000000000000000000000000000000000..131e265740f37d77b7c4a3676d2a7704ca3e4a29 GIT binary patch literal 8 McmZQz0D%Su009U9fdBvi literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab new file mode 100644 index 0000000000000000000000000000000000000000..49dfd8cf0c35cc8f69cc3bc6c715a7488a002e54 GIT binary patch literal 4096 zcmbR3vzw0r2$(jE2By2#kinXb6mkz-S1JhQMeDjE2By2#kinXb6mk0O=tB01EdGI{*Lx literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream new file mode 100644 index 0000000000000000000000000000000000000000..d86315ba75e7d44683eec4fb432687fd5976b9be GIT binary patch literal 4096 zcmd-G&&Mc1k(>yEqH(!3zuXtyCkNE zWSh%XIUj L-*d!r)W7l%{;NCk literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i new file mode 100644 index 0000000000000000000000000000000000000000..41a6da792bceecb494ff910b2358608b678ce367 GIT binary patch literal 32768 zcmeIuK@Gql5Jb@pSgJH`O$faq3N_VG0YwJMzESY!MTr_lfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C74igx==e^rHEK3dn0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyKp?Ha+|RH6 qJ!t_PCqRGz0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5;&6aqg2W(C3k literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len new file mode 100644 index 0000000000000000000000000000000000000000..131e265740f37d77b7c4a3676d2a7704ca3e4a29 GIT binary patch literal 8 McmZQz0D%Su009U9fdBvi literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab new file mode 100644 index 0000000000000000000000000000000000000000..51530698cf4e5fbd44339183475807a13635be84 GIT binary patch literal 4096 zcmbR3vzw0r2$(R literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream new file mode 100644 index 0000000000000000000000000000000000000000..b168a7b3775c732d604349beec38ecd24cb77cf1 GIT binary patch literal 4096 zcmeIuu?+wa5I|9-$|%+_f>I4qH5FIx$U6&#uryw3;52X}JgIBN82B{#n*z;({8oDuIGXeXLdhI{#Bo_zX z7Yy$`Lq?dBOSW{VT%NpCF4>T4iiYXT88)Xi);qKsR8i~gXy?bN7P85M#7;Y2Vt zN_(Q(fIh}BSLtB&5UPoe{79vK>dk|2I1wir^s2QAZ^Y^B{x=v&t8~467T?7ymb8%U z*A{=eIT$yLjyJOZQLrVrrE`8wy2Q(pYCg$lbg0VO664;|)3N2&(X6kCg+0MQ(2ezX I2amn}13YdtVgLXD literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i new file mode 100644 index 0000000000000000000000000000000000000000..9196d2b59d0d608f133ec403a79a91f1b8d5f6b2 GIT binary patch literal 32768 zcmeIuu?>JA6h+Y=U760t(xKRau!2j_P{<61;uq%)aPxBFh%<};0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&o6S&u(_bN5nEq4eIAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U vAV7cs0RjXz3p}egdmEdxas&tvAV7cs0RjXF5FkK+009C72oNAZ;FrJ$x>^S= literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len new file mode 100644 index 0000000000000000000000000000000000000000..131e265740f37d77b7c4a3676d2a7704ca3e4a29 GIT binary patch literal 8 McmZQz0D%Su009U9fdBvi literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab new file mode 100644 index 0000000000000000000000000000000000000000..bdf584a84b58bf0b45e9b3a4c946653433feaad2 GIT binary patch literal 4096 zcmbR3vzw0r2pB;G3eSnEDq8~2%LkOPe|RU{AdV_hQMeD jjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kgRc_9D*#r_JH literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream new file mode 100644 index 0000000000000000000000000000000000000000..d5abc42a57ab711d3c4ec3c4836d9376b2099e10 GIT binary patch literal 4096 zcmeIuK@LDL5Cu?&>6Y2sBEp7<#8O5xl4^@o>-^3k`R@p?RO2-CO*OA|H!0GWznw(h xoaB3oDF{75lV@|%!7tNdtZCUxVPgguzyJm?fB_6(00S7n00uCC0Sx?O-~(=K6ukfd literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len new file mode 100644 index 0000000000000000000000000000000000000000..130ab288134144812e637e1779d150d9a83c3d73 GIT binary patch literal 8 LcmZQz00V0P07C#g literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len new file mode 100644 index 0000000000000000000000000000000000000000..2a17e6e5bd9e7704741c2a3ae485eb2d2e302b87 GIT binary patch literal 8 LcmZQz0D}$y0FVHQ literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at new file mode 100644 index 0000000000000000000000000000000000000000..f2a68686e4306333f077165fd0021c38b125d8b4 GIT binary patch literal 97 zcmdOA@JLNeNi9+cN=?o$N>OmjFH#6dEh^3|E=kQR@klJr@J%cTOUx-v4KB$qN=#4H tW8etS%+7RA%uN-AF;rYq(-KQ_N<4E5a*Fx%vhz!FGV|hd^HWN5QUQxnBMSfk literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i new file mode 100644 index 0000000000000000000000000000000000000000..9d2eca8c0c3fa9f616c99d992a152577d3028e10 GIT binary patch literal 32768 zcmeIuQ4s(T6h*;nh#{6h63RpgKX3LlIGdIp5geSnEDq8~2%LkOPe|RU{AdV_hQMeD jjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kgRc_9D*#r_JH literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream new file mode 100644 index 0000000000000000000000000000000000000000..d5abc42a57ab711d3c4ec3c4836d9376b2099e10 GIT binary patch literal 4096 zcmeIuK@LDL5Cu?&>6Y2sBEp7<#8O5xl4^@o>-^3k`R@p?RO2-CO*OA|H!0GWznw(h xoaB3oDF{75lV@|%!7tNdtZCUxVPgguzyJm?fB_6(00S7n00uCC0Sx?O-~(=K6ukfd literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len new file mode 100644 index 0000000000000000000000000000000000000000..130ab288134144812e637e1779d150d9a83c3d73 GIT binary patch literal 8 LcmZQz00V0P07C#g literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len new file mode 100644 index 0000000000000000000000000000000000000000..2a17e6e5bd9e7704741c2a3ae485eb2d2e302b87 GIT binary patch literal 8 LcmZQz0D}$y0FVHQ literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at new file mode 100644 index 0000000000000000000000000000000000000000..5875372349163668e6e0a816c8855cd692143458 GIT binary patch literal 55 zcmdOA@JLNeNi9+cN=?o$N>OmjFH#6dEh^3|E=kQR@klJr@J%cTOUx-v4KB$qN=#2> HVE_RD6bTXt literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i new file mode 100644 index 0000000000000000000000000000000000000000..9d2eca8c0c3fa9f616c99d992a152577d3028e10 GIT binary patch literal 32768 zcmeIuQ4s(T6h*;nh#{6h63RpgKX3LlIGdIp5g^r3A~DbK&LAq2Q`Xctlfe>fUze{r2|Uoor1m#U()b6|j02Edt8oD6*gF%Ri=vpZt*{ H)|37LQ?Dlb literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len new file mode 100644 index 0000000000000000000000000000000000000000..1b1cb4d44c57c2d7a5122870fa6ac3e62ff7e94e GIT binary patch literal 8 KcmZQzfB*mh2mk>9 literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab new file mode 100644 index 0000000000000000000000000000000000000000..3ea04f76c98f3a4cdc56e84cf6b74d5030138d74 GIT binary patch literal 4096 zcmbR3vzw0r2)IB53hQMeD ljE2By2#kinXb6mkz-S1JhQMeDjE2By2#kinXb7N%007&8E=B+V literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream new file mode 100644 index 0000000000000000000000000000000000000000..56133765245d534d6cd58fbaaa715b1329cd7f96 GIT binary patch literal 4096 zcmeIuK?;B%5CzbILRxo_t`R}I7Og`h25p4&{*;R00b2f9>33#?N7OA6>8*a{kPm8$ zH_Mr_VQ0(pahY_muK_7c*6C9ME5Az literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len new file mode 100644 index 0000000000000000000000000000000000000000..b8b8413172e1315b6cc60273b2d4eb80b6e8efaa GIT binary patch literal 8 LcmZQz0E6iO0G|Mu literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.len b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.len new file mode 100644 index 0000000000000000000000000000000000000000..fd5292d4bdcdb76028e1eb3dd4835aa24aab9241 GIT binary patch literal 8 LcmZQz0D}tv0N4Q0 literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at new file mode 100644 index 0000000000000000000000000000000000000000..7c9e2992f2ba722ca444d6fdc69223ba5ab10242 GIT binary patch literal 109 zcmdOA@JLNeNi9+cN=?o$N>OmjFH#6dEh^3|E=kQR@klJr@J%cTOUx-v4KB$qN=#2> JVE_U0NC4&@5-b1! literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab_i b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab_i new file mode 100644 index 0000000000000000000000000000000000000000..6e45739fc5241e90bd4208a995800f57a83b3279 GIT binary patch literal 32768 zcmeI$Ax;B96b9f)L4hD(aYzn8!Zk=R2*MqDfhIM`I*>>l7?KJ|R$^(Y(A8a%HI=*@ zY_hw_PCDP%o%iPdKe_2B9VBNof%ka%=VSghS^y6d*kgfNbUXdM*yDy}R$D~v`ue0P zv%S^?2oNAZfB*pkeFeT_!DW4S)pw710t5&UAV7dXn?My8{%&^u|F=Q;PJjRb0t5&U zC`{lb`Zl*upM}*{mjD3*1O^s(jD3^o!{NYdts_8y009C72oNAZfB*pk1PBo5D6ovV zv*!4#!P=E4eEi|T>bj}`wYHM zejw2i-?nbxt>}~Xb*qL`tVcJqTZuI%Vl7&Hq>P>c*an6|Nn5dOs%O2xwZcm~p!_V~ z8?N2QPWc!%Q!Irr^ljsNM{rNssMMQN+u%&CNUuzuvsvLP=I9D{1ty{X-h&&Wt?Knn z8lutO!#r5%9tJy2m@ge{tet~3PwfqDx7cx1I$P=sxM#X-eUkQ^JKl$GK3wL#GZC}9 z)kFBr=^Un9A8dE$HcU`CV^;SC0R10Af-F1^@s6 literal 0 HcmV?d00001 diff --git a/wikigame/completable-future/build/tmp/compileJava/previous-compilation-data.bin b/wikigame/completable-future/build/tmp/compileJava/previous-compilation-data.bin new file mode 100644 index 0000000000000000000000000000000000000000..bf65c07a28fdc4debc909bda1d6cb5a412aef890 GIT binary patch literal 23846 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 O6_c(m&YRE;{{8@Hv)};$ literal 0 HcmV?d00001 diff --git a/wiki-game-completable-feature/src/main/java/point/rar/feature/Main.java b/wikigame/completable-future/src/main/java/Main.java similarity index 94% rename from wiki-game-completable-feature/src/main/java/point/rar/feature/Main.java rename to wikigame/completable-future/src/main/java/Main.java index 7ec4877..b765121 100644 --- a/wiki-game-completable-feature/src/main/java/point/rar/feature/Main.java +++ b/wikigame/completable-future/src/main/java/Main.java @@ -1,5 +1,3 @@ -package point.rar.feature; - public class Main { public static void main(String[] args) { long startTime = System.currentTimeMillis(); diff --git a/wiki-game-completable-feature/src/main/java/point/rar/feature/WikiGame.kt b/wikigame/completable-future/src/main/java/WikiGame.kt similarity index 80% rename from wiki-game-completable-feature/src/main/java/point/rar/feature/WikiGame.kt rename to wikigame/completable-future/src/main/java/WikiGame.kt index e89d78c..550f5fd 100644 --- a/wiki-game-completable-feature/src/main/java/point/rar/feature/WikiGame.kt +++ b/wikigame/completable-future/src/main/java/WikiGame.kt @@ -1,5 +1,3 @@ -package point.rar.feature - interface WikiGame { fun play(startPageTitle: String, endPageTitle: String, maxDepth: Int = 11): List } \ No newline at end of file diff --git a/wiki-game-completable-feature/src/main/java/point/rar/feature/WikiGameFutureImpl.java b/wikigame/completable-future/src/main/java/WikiGameFutureImpl.java similarity index 95% rename from wiki-game-completable-feature/src/main/java/point/rar/feature/WikiGameFutureImpl.java rename to wikigame/completable-future/src/main/java/WikiGameFutureImpl.java index 2b7acb7..1c8b9ea 100644 --- a/wiki-game-completable-feature/src/main/java/point/rar/feature/WikiGameFutureImpl.java +++ b/wikigame/completable-future/src/main/java/WikiGameFutureImpl.java @@ -1,12 +1,8 @@ -package point.rar.feature; - import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.http.client.utils.URIBuilder; import org.jetbrains.annotations.NotNull; -import point.rar.common.wiki.domain.model.Page; -import point.rar.common.wiki.domain.model.Link; -import point.rar.common.wiki.domain.model.WikiLinksResponse; +import point.rar.model.*; import java.io.IOException; import java.net.URI; @@ -34,7 +30,7 @@ public List play(String startPageTitle, String endPageTitle, int maxDept List> futures = new ArrayList<>(); do { - for (int i = 0; i < 100; i++) { + for (int i = 0; i < 10; i++) { Page curPage = rawPages.poll(); if (curPage == null) { break; diff --git a/wiki-game-completable-feature/src/main/java/point/rar/feature/WikiGameFutureSimpleImpl.java b/wikigame/completable-future/src/main/java/WikiGameFutureSimpleImpl.java similarity index 95% rename from wiki-game-completable-feature/src/main/java/point/rar/feature/WikiGameFutureSimpleImpl.java rename to wikigame/completable-future/src/main/java/WikiGameFutureSimpleImpl.java index 6d49c76..01a2c57 100644 --- a/wiki-game-completable-feature/src/main/java/point/rar/feature/WikiGameFutureSimpleImpl.java +++ b/wikigame/completable-future/src/main/java/WikiGameFutureSimpleImpl.java @@ -1,16 +1,11 @@ -package point.rar.feature; - import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; -import io.github.resilience4j.core.functions.CheckedRunnable; import io.github.resilience4j.ratelimiter.RateLimiter; import io.github.resilience4j.ratelimiter.RateLimiterConfig; import io.github.resilience4j.ratelimiter.RateLimiterRegistry; import org.apache.http.client.utils.URIBuilder; import org.jetbrains.annotations.NotNull; -import point.rar.common.wiki.domain.model.Link; -import point.rar.common.wiki.domain.model.Page; -import point.rar.common.wiki.domain.model.WikiLinksResponse; +import point.rar.model.*; import java.io.IOException; import java.net.URI; diff --git a/wiki-game-executor/src/main/java/point/rar/feature/WikiGameSerialImpl.java b/wikigame/completable-future/src/main/java/WikiGameSerialImpl.java similarity index 94% rename from wiki-game-executor/src/main/java/point/rar/feature/WikiGameSerialImpl.java rename to wikigame/completable-future/src/main/java/WikiGameSerialImpl.java index 431378b..301f6b9 100644 --- a/wiki-game-executor/src/main/java/point/rar/feature/WikiGameSerialImpl.java +++ b/wikigame/completable-future/src/main/java/WikiGameSerialImpl.java @@ -1,11 +1,7 @@ -package point.rar.feature; - import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import org.jetbrains.annotations.NotNull; -import point.rar.common.wiki.domain.model.Page; -import point.rar.common.wiki.domain.model.Link; -import point.rar.common.wiki.domain.model.WikiLinksResponse; +import point.rar.model.*; import java.io.IOException; import java.net.URI; diff --git a/wiki-game-coroutines/build.gradle.kts b/wikigame/coroutines/build.gradle.kts similarity index 53% rename from wiki-game-coroutines/build.gradle.kts rename to wikigame/coroutines/build.gradle.kts index 1afe23c..1858fcc 100644 --- a/wiki-game-coroutines/build.gradle.kts +++ b/wikigame/coroutines/build.gradle.kts @@ -1,26 +1,23 @@ -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile - plugins { id("java") - kotlin("jvm") version "1.8.10" - kotlin("plugin.serialization") version "1.8.10" + kotlin("jvm") version "1.9.10" } group = "point.rar" version = "1.0-SNAPSHOT" repositories { - mavenLocal() mavenCentral() } dependencies { - implementation("point.rar.common:wiki-game-common:2.0") - implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.14.2") - testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.1") - testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.1") + implementation(project(mapOf("path" to ":"))) + testImplementation(platform("org.junit:junit-bom:5.9.1")) + testImplementation("org.junit.jupiter:junit-jupiter") implementation(kotlin("stdlib-jdk8")) + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3") + val ktor_version = "2.2.3" implementation("io.ktor:ktor-client-core:$ktor_version") implementation("io.ktor:ktor-client-cio:$ktor_version") @@ -31,24 +28,15 @@ dependencies { implementation("org.slf4j:slf4j-api:$slf4j_version") implementation("org.slf4j:slf4j-simple:$slf4j_version") - val kotlinx_serialization_json_version = "1.4.1" - implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinx_serialization_json_version") - val resilience4jVersion = "2.0.0" implementation("io.github.resilience4j:resilience4j-kotlin:${resilience4jVersion}") implementation("io.github.resilience4j:resilience4j-ratelimiter:${resilience4jVersion}") implementation("io.github.resilience4j:resilience4j-retry:${resilience4jVersion}") } - -tasks.getByName("test") { +tasks.test { useJUnitPlatform() } -val compileKotlin: KotlinCompile by tasks -compileKotlin.kotlinOptions { - jvmTarget = "1.8" -} -val compileTestKotlin: KotlinCompile by tasks -compileTestKotlin.kotlinOptions { - jvmTarget = "1.8" +kotlin { + jvmToolchain(19) } \ No newline at end of file diff --git a/wiki-game-coroutines/src/main/java/point/rar/coroutines/Main.kt b/wikigame/coroutines/src/main/java/coroutines/Main.kt similarity index 69% rename from wiki-game-coroutines/src/main/java/point/rar/coroutines/Main.kt rename to wikigame/coroutines/src/main/java/coroutines/Main.kt index 7e83c8a..5377182 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/coroutines/Main.kt +++ b/wikigame/coroutines/src/main/java/coroutines/Main.kt @@ -1,7 +1,7 @@ -package point.rar.coroutines +package coroutines -import point.rar.coroutines.repository.WikiGame -import point.rar.coroutines.repository.WikiGameDumbImpl +import coroutines.repository.WikiGame +import coroutines.repository.WikiGameDumbImpl fun main(args: Array) { val wikiGame: WikiGame = WikiGameDumbImpl() diff --git a/wiki-game-coroutines/src/main/java/point/rar/coroutines/repository/WikiGame.kt b/wikigame/coroutines/src/main/java/coroutines/repository/WikiGame.kt similarity index 74% rename from wiki-game-coroutines/src/main/java/point/rar/coroutines/repository/WikiGame.kt rename to wikigame/coroutines/src/main/java/coroutines/repository/WikiGame.kt index e5e08ef..b1c3ef1 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/coroutines/repository/WikiGame.kt +++ b/wikigame/coroutines/src/main/java/coroutines/repository/WikiGame.kt @@ -1,4 +1,4 @@ -package point.rar.coroutines.repository +package coroutines.repository interface WikiGame { fun play(startPageTitle: String, endPageTitle: String, maxDepth: Int = 11): List diff --git a/wiki-game-coroutines/src/main/java/point/rar/coroutines/repository/WikiGameDumbImpl.kt b/wikigame/coroutines/src/main/java/coroutines/repository/WikiGameDumbImpl.kt similarity index 93% rename from wiki-game-coroutines/src/main/java/point/rar/coroutines/repository/WikiGameDumbImpl.kt rename to wikigame/coroutines/src/main/java/coroutines/repository/WikiGameDumbImpl.kt index b3a74bc..b63a7dd 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/coroutines/repository/WikiGameDumbImpl.kt +++ b/wikigame/coroutines/src/main/java/coroutines/repository/WikiGameDumbImpl.kt @@ -1,10 +1,10 @@ -package point.rar.coroutines.repository +package coroutines.repository import kotlinx.coroutines.* import kotlinx.coroutines.channels.Channel -import point.rar.common.wiki.domain.model.Page -import point.rar.coroutines.wiki.data.source.WikiRemoteDataSource -import point.rar.coroutines.wiki.WikiRemoteDataSourceImpl +import coroutines.wiki.data.source.WikiRemoteDataSource +import coroutines.wiki.WikiRemoteDataSourceImpl +import point.rar.model.Page import java.lang.RuntimeException import java.util.Optional import java.util.concurrent.ConcurrentHashMap diff --git a/wiki-game-coroutines/src/main/java/point/rar/coroutines/wiki/WikiRemoteDataSourceImpl.kt b/wikigame/coroutines/src/main/java/coroutines/wiki/WikiRemoteDataSourceImpl.kt similarity index 91% rename from wiki-game-coroutines/src/main/java/point/rar/coroutines/wiki/WikiRemoteDataSourceImpl.kt rename to wikigame/coroutines/src/main/java/coroutines/wiki/WikiRemoteDataSourceImpl.kt index 71fb4b3..1710448 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/coroutines/wiki/WikiRemoteDataSourceImpl.kt +++ b/wikigame/coroutines/src/main/java/coroutines/wiki/WikiRemoteDataSourceImpl.kt @@ -1,4 +1,4 @@ -package point.rar.coroutines.wiki +package coroutines.wiki import io.github.resilience4j.kotlin.ratelimiter.executeSuspendFunction import io.github.resilience4j.ratelimiter.RateLimiterConfig @@ -11,9 +11,9 @@ import io.ktor.client.request.get import io.ktor.client.request.parameter import io.ktor.serialization.kotlinx.json.json import kotlinx.serialization.json.Json -import point.rar.common.wiki.domain.model.WikiBacklinksResponse -import point.rar.common.wiki.domain.model.WikiLinksResponse -import point.rar.coroutines.wiki.data.source.WikiRemoteDataSource +import coroutines.wiki.data.source.WikiRemoteDataSource +import point.rar.model.WikiBacklinksResponse +import point.rar.model.WikiLinksResponse import java.time.Duration class WikiRemoteDataSourceImpl : WikiRemoteDataSource { diff --git a/wiki-game-coroutines/src/main/java/point/rar/coroutines/wiki/data/source/WikiRemoteDataSource.kt b/wikigame/coroutines/src/main/java/coroutines/wiki/data/source/WikiRemoteDataSource.kt similarity index 77% rename from wiki-game-coroutines/src/main/java/point/rar/coroutines/wiki/data/source/WikiRemoteDataSource.kt rename to wikigame/coroutines/src/main/java/coroutines/wiki/data/source/WikiRemoteDataSource.kt index bdbafd2..d1419cd 100644 --- a/wiki-game-coroutines/src/main/java/point/rar/coroutines/wiki/data/source/WikiRemoteDataSource.kt +++ b/wikigame/coroutines/src/main/java/coroutines/wiki/data/source/WikiRemoteDataSource.kt @@ -1,4 +1,4 @@ -package point.rar.coroutines.wiki.data.source +package coroutines.wiki.data.source interface WikiRemoteDataSource { suspend fun getLinksByTitle(title: String): List diff --git a/wikigame/executor/build.gradle.kts b/wikigame/executor/build.gradle.kts new file mode 100644 index 0000000..c8e56f3 --- /dev/null +++ b/wikigame/executor/build.gradle.kts @@ -0,0 +1,34 @@ +plugins { + id("java") + kotlin("jvm") version "1.9.10" +} + +group = "point.rar" +version = "1.0-SNAPSHOT" + +repositories { + mavenCentral() +} + +dependencies { + implementation(project(mapOf("path" to ":"))) + testImplementation(platform("org.junit:junit-bom:5.9.1")) + testImplementation("org.junit.jupiter:junit-jupiter") + + val kotlinVersion = "1.9.10" + implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion") + implementation("org.jetbrains.kotlin:kotlin-test:$kotlinVersion") + + implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.14.2") + implementation("org.apache.httpcomponents:httpclient:4.5.13") + implementation("io.github.resilience4j:resilience4j-timelimiter:2.1.0") + implementation("io.github.resilience4j:resilience4j-ratelimiter:2.1.0") +} + +tasks.test { + useJUnitPlatform() +} + +tasks.withType { + options.compilerArgs.add("--enable-preview") +} \ No newline at end of file diff --git a/wikigame/executor/build/classes/kotlin/main/META-INF/executor.kotlin_module b/wikigame/executor/build/classes/kotlin/main/META-INF/executor.kotlin_module new file mode 100644 index 0000000000000000000000000000000000000000..1e9f2ca4d180a083a06174d407c30581ce729120 GIT binary patch literal 24 YcmZQzU|?ooU|eSnEDq8~2%LkOPe|RU{AdV_hQMeD jjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kgRc_9D*#r_JH literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream new file mode 100644 index 0000000000000000000000000000000000000000..e1ab609e4c43355cd9ebe548e8fb2b45bcbf13a5 GIT binary patch literal 4096 zcmeIu%L#xm5I{kT$=S6B714_l1dp2(3^2d|0}L?000Rs#zyJe(8~6Z(*$~nI literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len new file mode 100644 index 0000000000000000000000000000000000000000..1c209ae2a7dc1bbbb98f55f92e253f91b6f5ef9d GIT binary patch literal 8 LcmZQz00Tn+0673M literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len new file mode 100644 index 0000000000000000000000000000000000000000..2a17e6e5bd9e7704741c2a3ae485eb2d2e302b87 GIT binary patch literal 8 LcmZQz0D}$y0FVHQ literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at new file mode 100644 index 0000000000000000000000000000000000000000..a5b615a3351f17d1d7f41d761376bdc800d97dd0 GIT binary patch literal 274 zcmbV`!3u&v6h(!8#D&|OPl!lOBTGzbDKF<$gKr#}Hv@fb-;yM>ug%>Y?%{|aN04a4 z8arcUm>C;ZXj!qt!R5e@62>!-$CEP_?)X{+tEj4vyL8jENl`}vpV;{cimO*7MMuDl zEPCTe4MM{-7uBmRXpBE_|Mx#i@CKe-p-19bR{bn1(`LOa4%s(6o>Nk7i=i literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i new file mode 100644 index 0000000000000000000000000000000000000000..264e3d2c81aba569068b339f59e7c27605f3f8ce GIT binary patch literal 32768 zcmeIu0Sy2k5CgFhoL~Zbct8`rKn9<53T{nHj}ah1fB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C73Ja{)e)gD!FGwdqfB*pk1PBly cK!5-N0t5&UAV7cs0RjXF5FkK+0D%t#E>b}PHUIzs literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i.len new file mode 100644 index 0000000000000000000000000000000000000000..131e265740f37d77b7c4a3676d2a7704ca3e4a29 GIT binary patch literal 8 McmZQz0D%Su009U9fdBvi literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab new file mode 100644 index 0000000000000000000000000000000000000000..bdf584a84b58bf0b45e9b3a4c946653433feaad2 GIT binary patch literal 4096 zcmbR3vzw0r2pB;G3eSnEDq8~2%LkOPe|RU{AdV_hQMeD jjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kgRc_9D*#r_JH literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream new file mode 100644 index 0000000000000000000000000000000000000000..bfcae2c8e2f3c522c3d0bbb9af7b5723c44b0000 GIT binary patch literal 4096 zcmeIuF%1A93;;0BIYR>X4vuA+{}&&mmC!iVwR7&mfB^#r3>YwAz<>b*1`HVZb>IPI C1p^lV literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len new file mode 100644 index 0000000000000000000000000000000000000000..9a6f654a2b1fe7f7cba4b266715a7a764968b486 GIT binary patch literal 8 LcmZQz00T|{01*HR literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len new file mode 100644 index 0000000000000000000000000000000000000000..2a17e6e5bd9e7704741c2a3ae485eb2d2e302b87 GIT binary patch literal 8 LcmZQz0D}$y0FVHQ literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at new file mode 100644 index 0000000000000000000000000000000000000000..53b2d29f95c6af74266544729b594570fda94d3b GIT binary patch literal 52 zcmdOA@JLNeNi9+cN=?o$N>OmjFH#6dEh^3|E=kQR@klJr@J%cTOUx-v4KB$qN=#2> HWMBXQ-PsZa literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i new file mode 100644 index 0000000000000000000000000000000000000000..0ea07a00c729455d91a6698c991502c763529461 GIT binary patch literal 32768 zcmeIuK@9*P5CpL$SmwtEVW>d~$heS>f=ScTBLV~n5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAW%$Ty`MA3F1BTd009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk c1PBlyK!5-N0t5&UAV7cs0RjXF5cpW&0s|le5&!@I literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i.len new file mode 100644 index 0000000000000000000000000000000000000000..131e265740f37d77b7c4a3676d2a7704ca3e4a29 GIT binary patch literal 8 McmZQz0D%Su009U9fdBvi literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab new file mode 100644 index 0000000000000000000000000000000000000000..bdf584a84b58bf0b45e9b3a4c946653433feaad2 GIT binary patch literal 4096 zcmbR3vzw0r2pB;G3eSnEDq8~2%LkOPe|RU{AdV_hQMeD jjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kgRc_9D*#r_JH literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream new file mode 100644 index 0000000000000000000000000000000000000000..bfcae2c8e2f3c522c3d0bbb9af7b5723c44b0000 GIT binary patch literal 4096 zcmeIuF%1A93;;0BIYR>X4vuA+{}&&mmC!iVwR7&mfB^#r3>YwAz<>b*1`HVZb>IPI C1p^lV literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len new file mode 100644 index 0000000000000000000000000000000000000000..9a6f654a2b1fe7f7cba4b266715a7a764968b486 GIT binary patch literal 8 LcmZQz00T|{01*HR literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len new file mode 100644 index 0000000000000000000000000000000000000000..2a17e6e5bd9e7704741c2a3ae485eb2d2e302b87 GIT binary patch literal 8 LcmZQz0D}$y0FVHQ literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at new file mode 100644 index 0000000000000000000000000000000000000000..7ffc2f7eae72d74f37a84f9223162e50017d1899 GIT binary patch literal 100 zcmWN`K@Ng25Cu?<(gkZr&wwJD7)dpm}}{?*wd A1^@s6 literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i new file mode 100644 index 0000000000000000000000000000000000000000..0ea07a00c729455d91a6698c991502c763529461 GIT binary patch literal 32768 zcmeIuK@9*P5CpL$SmwtEVW>d~$heS>f=ScTBLV~n5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAW%$Ty`MA3F1BTd009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk c1PBlyK!5-N0t5&UAV7cs0RjXF5cpW&0s|le5&!@I literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len new file mode 100644 index 0000000000000000000000000000000000000000..131e265740f37d77b7c4a3676d2a7704ca3e4a29 GIT binary patch literal 8 McmZQz0D%Su009U9fdBvi literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab new file mode 100644 index 0000000000000000000000000000000000000000..4bd7a9b70da379f8d9d0bff8d516fb08256ab731 GIT binary patch literal 4096 zcmbR3vzw0r2$(jE2By2#kinXb6mkz-S1JhQMeDjE2By2#kinXb6mk0O=tB0HuEpMF0Q* literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream new file mode 100644 index 0000000000000000000000000000000000000000..d86315ba75e7d44683eec4fb432687fd5976b9be GIT binary patch literal 4096 zcmd-G&&OmjFH#6dEh^3|E=kQR@klJr@J%cTOUx-v4KB$qN=#2R zWH3+(2=e!Gbq1QRDCF+M~W@ox5=BDapmyn?a E0B4Fc2mk;8 literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i new file mode 100644 index 0000000000000000000000000000000000000000..41a6da792bceecb494ff910b2358608b678ce367 GIT binary patch literal 32768 zcmeIuK@Gql5Jb@pSgJH`O$faq3N_VG0YwJMzESY!MTr_lfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C74igx==e^rHEK3dn0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyKp?Ha+|RH6 qJ!t_PCqRGz0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5;&6aqg2W(C3k literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len new file mode 100644 index 0000000000000000000000000000000000000000..131e265740f37d77b7c4a3676d2a7704ca3e4a29 GIT binary patch literal 8 McmZQz0D%Su009U9fdBvi literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab new file mode 100644 index 0000000000000000000000000000000000000000..fe53097dddf9fb8bf8ea494ffa3fdba96f831055 GIT binary patch literal 4096 zcmbR3vzw0r2$(Ia!dMKqAgV$b*25BLrr9CfZ)nGK?8iwms6v#BVaY zO-0u}4yLUoV>8MBE^Wmy;d61H@I>7^H})W#$Q^Gl^6P9k45d4Qk)V$lY7Vah-vGCY BFl_(; literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i new file mode 100644 index 0000000000000000000000000000000000000000..9196d2b59d0d608f133ec403a79a91f1b8d5f6b2 GIT binary patch literal 32768 zcmeIuu?>JA6h+Y=U760t(xKRau!2j_P{<61;uq%)aPxBFh%<};0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&o6S&u(_bN5nEq4eIAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U vAV7cs0RjXz3p}egdmEdxas&tvAV7cs0RjXF5FkK+009C72oNAZ;FrJ$x>^S= literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len new file mode 100644 index 0000000000000000000000000000000000000000..131e265740f37d77b7c4a3676d2a7704ca3e4a29 GIT binary patch literal 8 McmZQz0D%Su009U9fdBvi literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab new file mode 100644 index 0000000000000000000000000000000000000000..bdf584a84b58bf0b45e9b3a4c946653433feaad2 GIT binary patch literal 4096 zcmbR3vzw0r2pB;G3eSnEDq8~2%LkOPe|RU{AdV_hQMeD jjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kgRc_9D*#r_JH literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream new file mode 100644 index 0000000000000000000000000000000000000000..e1ab609e4c43355cd9ebe548e8fb2b45bcbf13a5 GIT binary patch literal 4096 zcmeIu%L#xm5I{kT$=S6B714_l1dp2(3^2d|0}L?000Rs#zyJe(8~6Z(*$~nI literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len new file mode 100644 index 0000000000000000000000000000000000000000..1c209ae2a7dc1bbbb98f55f92e253f91b6f5ef9d GIT binary patch literal 8 LcmZQz00Tn+0673M literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len new file mode 100644 index 0000000000000000000000000000000000000000..2a17e6e5bd9e7704741c2a3ae485eb2d2e302b87 GIT binary patch literal 8 LcmZQz0D}$y0FVHQ literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at new file mode 100644 index 0000000000000000000000000000000000000000..f2a68686e4306333f077165fd0021c38b125d8b4 GIT binary patch literal 97 zcmdOA@JLNeNi9+cN=?o$N>OmjFH#6dEh^3|E=kQR@klJr@J%cTOUx-v4KB$qN=#4H tW8etS%+7RA%uN-AF;rYq(-KQ_N<4E5a*Fx%vhz!FGV|hd^HWN5QUQxnBMSfk literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i new file mode 100644 index 0000000000000000000000000000000000000000..264e3d2c81aba569068b339f59e7c27605f3f8ce GIT binary patch literal 32768 zcmeIu0Sy2k5CgFhoL~Zbct8`rKn9<53T{nHj}ah1fB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C73Ja{)e)gD!FGwdqfB*pk1PBly cK!5-N0t5&UAV7cs0RjXF5FkK+0D%t#E>b}PHUIzs literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len new file mode 100644 index 0000000000000000000000000000000000000000..131e265740f37d77b7c4a3676d2a7704ca3e4a29 GIT binary patch literal 8 McmZQz0D%Su009U9fdBvi literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/counters.tab b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/counters.tab new file mode 100644 index 0000000..166c057 --- /dev/null +++ b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/counters.tab @@ -0,0 +1,2 @@ +1 +0 \ No newline at end of file diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab new file mode 100644 index 0000000000000000000000000000000000000000..bdf584a84b58bf0b45e9b3a4c946653433feaad2 GIT binary patch literal 4096 zcmbR3vzw0r2pB;G3eSnEDq8~2%LkOPe|RU{AdV_hQMeD jjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kgRc_9D*#r_JH literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream new file mode 100644 index 0000000000000000000000000000000000000000..e1ab609e4c43355cd9ebe548e8fb2b45bcbf13a5 GIT binary patch literal 4096 zcmeIu%L#xm5I{kT$=S6B714_l1dp2(3^2d|0}L?000Rs#zyJe(8~6Z(*$~nI literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len new file mode 100644 index 0000000000000000000000000000000000000000..1c209ae2a7dc1bbbb98f55f92e253f91b6f5ef9d GIT binary patch literal 8 LcmZQz00Tn+0673M literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len new file mode 100644 index 0000000000000000000000000000000000000000..2a17e6e5bd9e7704741c2a3ae485eb2d2e302b87 GIT binary patch literal 8 LcmZQz0D}$y0FVHQ literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at new file mode 100644 index 0000000000000000000000000000000000000000..5875372349163668e6e0a816c8855cd692143458 GIT binary patch literal 55 zcmdOA@JLNeNi9+cN=?o$N>OmjFH#6dEh^3|E=kQR@klJr@J%cTOUx-v4KB$qN=#2> HVE_RD6bTXt literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i new file mode 100644 index 0000000000000000000000000000000000000000..264e3d2c81aba569068b339f59e7c27605f3f8ce GIT binary patch literal 32768 zcmeIu0Sy2k5CgFhoL~Zbct8`rKn9<53T{nHj}ah1fB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C73Ja{)e)gD!FGwdqfB*pk1PBly cK!5-N0t5&UAV7cs0RjXF5FkK+0D%t#E>b}PHUIzs literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i.len new file mode 100644 index 0000000000000000000000000000000000000000..131e265740f37d77b7c4a3676d2a7704ca3e4a29 GIT binary patch literal 8 McmZQz0D%Su009U9fdBvi literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab new file mode 100644 index 0000000000000000000000000000000000000000..8aad32b3b84c79ee82814f17430d858dce49687b GIT binary patch literal 4096 zcmbR3vzw0r2pB;G3m}}{?*wd A1^@s6 literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len new file mode 100644 index 0000000000000000000000000000000000000000..1b1cb4d44c57c2d7a5122870fa6ac3e62ff7e94e GIT binary patch literal 8 KcmZQzfB*mh2mk>9 literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab new file mode 100644 index 0000000000000000000000000000000000000000..3ea04f76c98f3a4cdc56e84cf6b74d5030138d74 GIT binary patch literal 4096 zcmbR3vzw0r2)IB53hQMeD ljE2By2#kinXb6mkz-S1JhQMeDjE2By2#kinXb7N%007&8E=B+V literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream new file mode 100644 index 0000000000000000000000000000000000000000..56133765245d534d6cd58fbaaa715b1329cd7f96 GIT binary patch literal 4096 zcmeIuK?;B%5CzbILRxo_t`R}I7Og`h25p4&{*;R00b2f9>33#?N7OA6>8*a{kPm8$ zH_Mr_VQ0(pahY_muK_7c*6C9ME5Az literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len new file mode 100644 index 0000000000000000000000000000000000000000..b8b8413172e1315b6cc60273b2d4eb80b6e8efaa GIT binary patch literal 8 LcmZQz0E6iO0G|Mu literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.len new file mode 100644 index 0000000000000000000000000000000000000000..fd5292d4bdcdb76028e1eb3dd4835aa24aab9241 GIT binary patch literal 8 LcmZQz0D}tv0N4Q0 literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at new file mode 100644 index 0000000000000000000000000000000000000000..7c9e2992f2ba722ca444d6fdc69223ba5ab10242 GIT binary patch literal 109 zcmdOA@JLNeNi9+cN=?o$N>OmjFH#6dEh^3|E=kQR@klJr@J%cTOUx-v4KB$qN=#2> JVE_U0NC4&@5-b1! literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab_i b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab_i new file mode 100644 index 0000000000000000000000000000000000000000..6e45739fc5241e90bd4208a995800f57a83b3279 GIT binary patch literal 32768 zcmeI$Ax;B96b9f)L4hD(aYzn8!Zk=R2*MqDfhIM`I*>>l7?KJ|R$^(Y(A8a%HI=*@ zY_hw_PCDP%o%iPdKe_2B9VBNof%ka%=VSghS^y6d*kgfNbUXdM*yDy}R$D~v`ue0P zv%S^?2oNAZfB*pkeFeT_!DW4S)pw710t5&UAV7dXn?My8{%&^u|F=Q;PJjRb0t5&U zC`{lb`Zl*upM}*{mjD3*1O^s(jD3^o!{NYdts_8y009C72oNAZfB*pk1PBo5D6ovV zv*!4#pF literal 0 HcmV?d00001 diff --git a/wikigame/executor/build/kotlin/compileKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin b/wikigame/executor/build/kotlin/compileKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin new file mode 100644 index 0000000000000000000000000000000000000000..1d79bd473dd25d9e9b2662a4ea3654f93ac01f8f GIT binary patch literal 692 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 PP>gS<4N+c%V(|9|!wdG} literal 0 HcmV?d00001 diff --git a/wiki-game-executor/src/main/java/point/rar/feature/Main.java b/wikigame/executor/src/main/java/Main.java similarity index 94% rename from wiki-game-executor/src/main/java/point/rar/feature/Main.java rename to wikigame/executor/src/main/java/Main.java index 1ad37f4..eca8b2e 100644 --- a/wiki-game-executor/src/main/java/point/rar/feature/Main.java +++ b/wikigame/executor/src/main/java/Main.java @@ -1,5 +1,3 @@ -package point.rar.feature; - public class Main { public static void main(String[] args) { long startTime = System.currentTimeMillis(); diff --git a/wiki-game-executor/src/main/java/point/rar/feature/WikiGame.kt b/wikigame/executor/src/main/java/WikiGame.kt similarity index 80% rename from wiki-game-executor/src/main/java/point/rar/feature/WikiGame.kt rename to wikigame/executor/src/main/java/WikiGame.kt index e89d78c..550f5fd 100644 --- a/wiki-game-executor/src/main/java/point/rar/feature/WikiGame.kt +++ b/wikigame/executor/src/main/java/WikiGame.kt @@ -1,5 +1,3 @@ -package point.rar.feature - interface WikiGame { fun play(startPageTitle: String, endPageTitle: String, maxDepth: Int = 11): List } \ No newline at end of file diff --git a/wiki-game-executor/src/main/java/point/rar/feature/WikiGameExecutorImpl.java b/wikigame/executor/src/main/java/WikiGameExecutorImpl.java similarity index 96% rename from wiki-game-executor/src/main/java/point/rar/feature/WikiGameExecutorImpl.java rename to wikigame/executor/src/main/java/WikiGameExecutorImpl.java index e514a8b..700d137 100644 --- a/wiki-game-executor/src/main/java/point/rar/feature/WikiGameExecutorImpl.java +++ b/wikigame/executor/src/main/java/WikiGameExecutorImpl.java @@ -1,5 +1,3 @@ -package point.rar.feature; - import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import io.github.resilience4j.ratelimiter.RateLimiter; @@ -7,9 +5,7 @@ import io.github.resilience4j.ratelimiter.RateLimiterRegistry; import org.apache.http.client.utils.URIBuilder; import org.jetbrains.annotations.NotNull; -import point.rar.common.wiki.domain.model.Page; -import point.rar.common.wiki.domain.model.Link; -import point.rar.common.wiki.domain.model.WikiLinksResponse; +import point.rar.model.*; import java.net.URI; import java.net.URISyntaxException; diff --git a/wiki-game-completable-feature/src/main/java/point/rar/feature/WikiGameSerialImpl.java b/wikigame/executor/src/main/java/WikiGameSerialImpl.java similarity index 94% rename from wiki-game-completable-feature/src/main/java/point/rar/feature/WikiGameSerialImpl.java rename to wikigame/executor/src/main/java/WikiGameSerialImpl.java index 431378b..301f6b9 100644 --- a/wiki-game-completable-feature/src/main/java/point/rar/feature/WikiGameSerialImpl.java +++ b/wikigame/executor/src/main/java/WikiGameSerialImpl.java @@ -1,11 +1,7 @@ -package point.rar.feature; - import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import org.jetbrains.annotations.NotNull; -import point.rar.common.wiki.domain.model.Page; -import point.rar.common.wiki.domain.model.Link; -import point.rar.common.wiki.domain.model.WikiLinksResponse; +import point.rar.model.*; import java.io.IOException; import java.net.URI; diff --git a/wiki-game-coroutines/gradle/wrapper/gradle-wrapper.properties b/wikigame/gradle/wrapper/gradle-wrapper.properties similarity index 86% rename from wiki-game-coroutines/gradle/wrapper/gradle-wrapper.properties rename to wikigame/gradle/wrapper/gradle-wrapper.properties index 070cb70..9c9dcd7 100644 --- a/wiki-game-coroutines/gradle/wrapper/gradle-wrapper.properties +++ b/wikigame/gradle/wrapper/gradle-wrapper.properties @@ -1,3 +1,4 @@ +#Sat Sep 02 18:40:37 MSK 2023 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip diff --git a/wiki-game-coroutines/gradlew b/wikigame/gradlew similarity index 98% rename from wiki-game-coroutines/gradlew rename to wikigame/gradlew index a69d9cb..1b6c787 100755 --- a/wiki-game-coroutines/gradlew +++ b/wikigame/gradlew @@ -205,12 +205,6 @@ set -- \ org.gradle.wrapper.GradleWrapperMain \ "$@" -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - # Use "xargs" to parse quoted args. # # With -n1 it outputs one arg per line, with the quotes and backslashes removed. diff --git a/wiki-game-coroutines/gradlew.bat b/wikigame/gradlew.bat similarity index 89% rename from wiki-game-coroutines/gradlew.bat rename to wikigame/gradlew.bat index f127cfd..ac1b06f 100644 --- a/wiki-game-coroutines/gradlew.bat +++ b/wikigame/gradlew.bat @@ -1,91 +1,89 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/wikigame/settings.gradle.kts b/wikigame/settings.gradle.kts new file mode 100644 index 0000000..a80f656 --- /dev/null +++ b/wikigame/settings.gradle.kts @@ -0,0 +1,7 @@ +plugins { + id("org.gradle.toolchains.foojay-resolver-convention") version "0.5.0" +} +rootProject.name = "wikigame" +include("coroutines") +include("executor") +include("completable-future") diff --git a/wiki-game-common/src/main/java/point/rar/common/Main.java b/wikigame/src/main/java/point/rar/Main.java similarity index 81% rename from wiki-game-common/src/main/java/point/rar/common/Main.java rename to wikigame/src/main/java/point/rar/Main.java index bbf6a58..23ff025 100644 --- a/wiki-game-common/src/main/java/point/rar/common/Main.java +++ b/wikigame/src/main/java/point/rar/Main.java @@ -1,4 +1,4 @@ -package point.rar.common; +package point.rar; public class Main { public static void main(String[] args) { diff --git a/wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/Link.kt b/wikigame/src/main/java/point/rar/model/Link.kt similarity index 70% rename from wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/Link.kt rename to wikigame/src/main/java/point/rar/model/Link.kt index 2469c5d..7168dc8 100644 --- a/wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/Link.kt +++ b/wikigame/src/main/java/point/rar/model/Link.kt @@ -1,4 +1,4 @@ -package point.rar.common.wiki.domain.model +package point.rar.model import kotlinx.serialization.Serializable diff --git a/wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/Page.kt b/wikigame/src/main/java/point/rar/model/Page.kt similarity index 80% rename from wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/Page.kt rename to wikigame/src/main/java/point/rar/model/Page.kt index 184c91a..f67a8e5 100644 --- a/wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/Page.kt +++ b/wikigame/src/main/java/point/rar/model/Page.kt @@ -1,4 +1,4 @@ -package point.rar.common.wiki.domain.model +package point.rar.model data class Page(val title: String, val parentPage: Page?) : Comparable { override fun compareTo(other: Page): Int { diff --git a/wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/PageLinks.kt b/wikigame/src/main/java/point/rar/model/PageLinks.kt similarity index 74% rename from wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/PageLinks.kt rename to wikigame/src/main/java/point/rar/model/PageLinks.kt index 57f0f5c..693fe8a 100644 --- a/wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/PageLinks.kt +++ b/wikigame/src/main/java/point/rar/model/PageLinks.kt @@ -1,4 +1,4 @@ -package point.rar.common.wiki.domain.model +package point.rar.model import kotlinx.serialization.Serializable diff --git a/wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/QueryBacklinks.kt b/wikigame/src/main/java/point/rar/model/QueryBacklinks.kt similarity index 54% rename from wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/QueryBacklinks.kt rename to wikigame/src/main/java/point/rar/model/QueryBacklinks.kt index 56ad7f4..efe2d87 100644 --- a/wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/QueryBacklinks.kt +++ b/wikigame/src/main/java/point/rar/model/QueryBacklinks.kt @@ -1,8 +1,8 @@ -package point.rar.common.wiki.domain.model +package point.rar.model import kotlinx.serialization.Serializable @Serializable data class QueryBacklinks( - val backlinks: List, + val backlinks: List, ) diff --git a/wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/QueryLinks.kt b/wikigame/src/main/java/point/rar/model/QueryLinks.kt similarity index 75% rename from wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/QueryLinks.kt rename to wikigame/src/main/java/point/rar/model/QueryLinks.kt index 6500262..4288c78 100644 --- a/wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/QueryLinks.kt +++ b/wikigame/src/main/java/point/rar/model/QueryLinks.kt @@ -1,4 +1,4 @@ -package point.rar.common.wiki.domain.model +package point.rar.model import kotlinx.serialization.Serializable diff --git a/wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/WikiBacklinksResponse.kt b/wikigame/src/main/java/point/rar/model/WikiBacklinksResponse.kt similarity index 55% rename from wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/WikiBacklinksResponse.kt rename to wikigame/src/main/java/point/rar/model/WikiBacklinksResponse.kt index 9421fd6..bf09bf6 100644 --- a/wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/WikiBacklinksResponse.kt +++ b/wikigame/src/main/java/point/rar/model/WikiBacklinksResponse.kt @@ -1,8 +1,8 @@ -package point.rar.common.wiki.domain.model +package point.rar.model import kotlinx.serialization.Serializable @Serializable data class WikiBacklinksResponse( - val query: QueryBacklinks, + val query: QueryBacklinks, ) diff --git a/wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/WikiLinksResponse.kt b/wikigame/src/main/java/point/rar/model/WikiLinksResponse.kt similarity index 76% rename from wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/WikiLinksResponse.kt rename to wikigame/src/main/java/point/rar/model/WikiLinksResponse.kt index 2c70ca6..4eccdb0 100644 --- a/wiki-game-common/src/main/java/point/rar/common/wiki/domain/model/WikiLinksResponse.kt +++ b/wikigame/src/main/java/point/rar/model/WikiLinksResponse.kt @@ -1,4 +1,4 @@ -package point.rar.common.wiki.domain.model +package point.rar.model import kotlinx.serialization.Serializable From 36ee1092cb8fe03f588df22c88b32c1c529b00a9 Mon Sep 17 00:00:00 2001 From: Daniil Lyubaev Date: Sat, 2 Sep 2023 21:05:09 +0300 Subject: [PATCH 31/58] rm --- wikigame/.gitignore | 4 ++++ wikigame/.gradle/7.6/checksums/checksums.lock | Bin 17 -> 0 bytes .../dependencies-accessors.lock | Bin 17 -> 0 bytes .../7.6/dependencies-accessors/gc.properties | 0 .../7.6/executionHistory/executionHistory.bin | Bin 109951 -> 0 bytes .../7.6/executionHistory/executionHistory.lock | Bin 17 -> 0 bytes .../.gradle/7.6/fileChanges/last-build.bin | Bin 1 -> 0 bytes wikigame/.gradle/7.6/fileHashes/fileHashes.bin | Bin 31797 -> 0 bytes .../.gradle/7.6/fileHashes/fileHashes.lock | Bin 17 -> 0 bytes .../7.6/fileHashes/resourceHashesCache.bin | Bin 19857 -> 0 bytes wikigame/.gradle/7.6/gc.properties | 0 .../buildOutputCleanup/buildOutputCleanup.lock | Bin 17 -> 0 bytes .../buildOutputCleanup/cache.properties | 2 -- .../.gradle/buildOutputCleanup/outputFiles.bin | Bin 19919 -> 0 bytes wikigame/.gradle/file-system.probe | Bin 8 -> 0 bytes wikigame/.gradle/vcs-1/gc.properties | 0 .../main/META-INF/wikigame.kotlin_module | Bin 24 -> 0 bytes .../caches-jvm/inputs/source-to-output.tab | Bin 4096 -> 0 bytes .../inputs/source-to-output.tab.keystream | Bin 4096 -> 0 bytes .../inputs/source-to-output.tab.keystream.len | Bin 8 -> 0 bytes .../caches-jvm/inputs/source-to-output.tab.len | Bin 8 -> 0 bytes .../inputs/source-to-output.tab.values.at | Bin 2131 -> 0 bytes .../caches-jvm/inputs/source-to-output.tab_i | Bin 32768 -> 0 bytes .../inputs/source-to-output.tab_i.len | Bin 8 -> 0 bytes .../caches-jvm/jvm/kotlin/class-attributes.tab | Bin 4096 -> 0 bytes .../jvm/kotlin/class-attributes.tab.keystream | Bin 4096 -> 0 bytes .../kotlin/class-attributes.tab.keystream.len | Bin 8 -> 0 bytes .../jvm/kotlin/class-attributes.tab.len | Bin 8 -> 0 bytes .../jvm/kotlin/class-attributes.tab.values.at | Bin 106 -> 0 bytes .../jvm/kotlin/class-attributes.tab_i | Bin 32768 -> 0 bytes .../jvm/kotlin/class-attributes.tab_i.len | Bin 8 -> 0 bytes .../jvm/kotlin/class-fq-name-to-source.tab | Bin 4096 -> 0 bytes .../class-fq-name-to-source.tab.keystream | Bin 4096 -> 0 bytes .../class-fq-name-to-source.tab.keystream.len | Bin 8 -> 0 bytes .../jvm/kotlin/class-fq-name-to-source.tab.len | Bin 8 -> 0 bytes .../class-fq-name-to-source.tab.values.at | Bin 1228 -> 0 bytes .../jvm/kotlin/class-fq-name-to-source.tab_i | Bin 32768 -> 0 bytes .../kotlin/class-fq-name-to-source.tab_i.len | Bin 8 -> 0 bytes .../jvm/kotlin/internal-name-to-source.tab | Bin 4096 -> 0 bytes .../internal-name-to-source.tab.keystream | Bin 4096 -> 0 bytes .../internal-name-to-source.tab.keystream.len | Bin 8 -> 0 bytes .../jvm/kotlin/internal-name-to-source.tab.len | Bin 8 -> 0 bytes .../internal-name-to-source.tab.values.at | Bin 1228 -> 0 bytes .../jvm/kotlin/internal-name-to-source.tab_i | Bin 32768 -> 0 bytes .../kotlin/internal-name-to-source.tab_i.len | Bin 8 -> 0 bytes .../cacheable/caches-jvm/jvm/kotlin/proto.tab | Bin 4096 -> 0 bytes .../caches-jvm/jvm/kotlin/proto.tab.keystream | Bin 4096 -> 0 bytes .../jvm/kotlin/proto.tab.keystream.len | Bin 8 -> 0 bytes .../caches-jvm/jvm/kotlin/proto.tab.len | Bin 8 -> 0 bytes .../caches-jvm/jvm/kotlin/proto.tab.values.at | Bin 11251 -> 0 bytes .../caches-jvm/jvm/kotlin/proto.tab_i | Bin 32768 -> 0 bytes .../caches-jvm/jvm/kotlin/proto.tab_i.len | Bin 8 -> 0 bytes .../jvm/kotlin/source-to-classes.tab | Bin 4096 -> 0 bytes .../jvm/kotlin/source-to-classes.tab.keystream | Bin 4096 -> 0 bytes .../kotlin/source-to-classes.tab.keystream.len | Bin 8 -> 0 bytes .../jvm/kotlin/source-to-classes.tab.len | Bin 8 -> 0 bytes .../jvm/kotlin/source-to-classes.tab.values.at | Bin 852 -> 0 bytes .../jvm/kotlin/source-to-classes.tab_i | Bin 32768 -> 0 bytes .../jvm/kotlin/source-to-classes.tab_i.len | Bin 8 -> 0 bytes .../caches-jvm/jvm/kotlin/subtypes.tab | Bin 4096 -> 0 bytes .../jvm/kotlin/subtypes.tab.keystream | Bin 4096 -> 0 bytes .../jvm/kotlin/subtypes.tab.keystream.len | Bin 8 -> 0 bytes .../caches-jvm/jvm/kotlin/subtypes.tab.len | Bin 8 -> 0 bytes .../jvm/kotlin/subtypes.tab.values.at | Bin 324 -> 0 bytes .../caches-jvm/jvm/kotlin/subtypes.tab_i | Bin 32768 -> 0 bytes .../caches-jvm/jvm/kotlin/subtypes.tab_i.len | Bin 8 -> 0 bytes .../caches-jvm/jvm/kotlin/supertypes.tab | Bin 4096 -> 0 bytes .../jvm/kotlin/supertypes.tab.keystream | Bin 4096 -> 0 bytes .../jvm/kotlin/supertypes.tab.keystream.len | Bin 8 -> 0 bytes .../caches-jvm/jvm/kotlin/supertypes.tab.len | Bin 8 -> 0 bytes .../jvm/kotlin/supertypes.tab.values.at | Bin 387 -> 0 bytes .../caches-jvm/jvm/kotlin/supertypes.tab_i | Bin 32768 -> 0 bytes .../caches-jvm/jvm/kotlin/supertypes.tab_i.len | Bin 8 -> 0 bytes .../cacheable/caches-jvm/lookups/counters.tab | 2 -- .../caches-jvm/lookups/file-to-id.tab | Bin 4096 -> 0 bytes .../lookups/file-to-id.tab.keystream | Bin 4096 -> 0 bytes .../lookups/file-to-id.tab.keystream.len | Bin 8 -> 0 bytes .../caches-jvm/lookups/file-to-id.tab.len | Bin 8 -> 0 bytes .../lookups/file-to-id.tab.values.at | Bin 91 -> 0 bytes .../caches-jvm/lookups/file-to-id.tab_i | Bin 32768 -> 0 bytes .../caches-jvm/lookups/file-to-id.tab_i.len | Bin 8 -> 0 bytes .../caches-jvm/lookups/id-to-file.tab | Bin 4096 -> 0 bytes .../lookups/id-to-file.tab.keystream | Bin 4096 -> 0 bytes .../lookups/id-to-file.tab.keystream.len | Bin 8 -> 0 bytes .../caches-jvm/lookups/id-to-file.tab.len | Bin 8 -> 0 bytes .../lookups/id-to-file.tab.values.at | Bin 478 -> 0 bytes .../caches-jvm/lookups/id-to-file.tab_i | Bin 32768 -> 0 bytes .../caches-jvm/lookups/id-to-file.tab_i.len | Bin 8 -> 0 bytes .../cacheable/caches-jvm/lookups/lookups.tab | Bin 4096 -> 0 bytes .../caches-jvm/lookups/lookups.tab.keystream | Bin 4096 -> 0 bytes .../lookups/lookups.tab.keystream.len | Bin 8 -> 0 bytes .../caches-jvm/lookups/lookups.tab.len | Bin 8 -> 0 bytes .../caches-jvm/lookups/lookups.tab.values.at | Bin 707 -> 0 bytes .../cacheable/caches-jvm/lookups/lookups.tab_i | Bin 32768 -> 0 bytes .../caches-jvm/lookups/lookups.tab_i.len | Bin 8 -> 0 bytes .../compileKotlin/cacheable/last-build.bin | Bin 18 -> 0 bytes .../shrunk-classpath-snapshot.bin | Bin 1890 -> 0 bytes .../local-state/build-history.bin | Bin 31 -> 0 bytes .../compileJava/previous-compilation-data.bin | Bin 3266 -> 0 bytes wikigame/build/tmp/jar/MANIFEST.MF | 2 -- .../META-INF/completable-future.kotlin_module | Bin 24 -> 0 bytes .../caches-jvm/inputs/source-to-output.tab | Bin 4096 -> 0 bytes .../inputs/source-to-output.tab.keystream | Bin 4096 -> 0 bytes .../inputs/source-to-output.tab.keystream.len | Bin 8 -> 0 bytes .../caches-jvm/inputs/source-to-output.tab.len | Bin 8 -> 0 bytes .../inputs/source-to-output.tab.values.at | Bin 314 -> 0 bytes .../caches-jvm/inputs/source-to-output.tab_i | Bin 32768 -> 0 bytes .../inputs/source-to-output.tab_i.len | Bin 8 -> 0 bytes .../caches-jvm/jvm/kotlin/class-attributes.tab | Bin 4096 -> 0 bytes .../jvm/kotlin/class-attributes.tab.keystream | Bin 4096 -> 0 bytes .../kotlin/class-attributes.tab.keystream.len | Bin 8 -> 0 bytes .../jvm/kotlin/class-attributes.tab.len | Bin 8 -> 0 bytes .../jvm/kotlin/class-attributes.tab.values.at | Bin 52 -> 0 bytes .../jvm/kotlin/class-attributes.tab_i | Bin 32768 -> 0 bytes .../jvm/kotlin/class-attributes.tab_i.len | Bin 8 -> 0 bytes .../jvm/kotlin/class-fq-name-to-source.tab | Bin 4096 -> 0 bytes .../class-fq-name-to-source.tab.keystream | Bin 4096 -> 0 bytes .../class-fq-name-to-source.tab.keystream.len | Bin 8 -> 0 bytes .../jvm/kotlin/class-fq-name-to-source.tab.len | Bin 8 -> 0 bytes .../class-fq-name-to-source.tab.values.at | Bin 110 -> 0 bytes .../jvm/kotlin/class-fq-name-to-source.tab_i | Bin 32768 -> 0 bytes .../kotlin/class-fq-name-to-source.tab_i.len | Bin 8 -> 0 bytes .../jvm/kotlin/internal-name-to-source.tab | Bin 4096 -> 0 bytes .../internal-name-to-source.tab.keystream | Bin 4096 -> 0 bytes .../internal-name-to-source.tab.keystream.len | Bin 8 -> 0 bytes .../jvm/kotlin/internal-name-to-source.tab.len | Bin 8 -> 0 bytes .../internal-name-to-source.tab.values.at | Bin 171 -> 0 bytes .../jvm/kotlin/internal-name-to-source.tab_i | Bin 32768 -> 0 bytes .../kotlin/internal-name-to-source.tab_i.len | Bin 8 -> 0 bytes .../cacheable/caches-jvm/jvm/kotlin/proto.tab | Bin 4096 -> 0 bytes .../caches-jvm/jvm/kotlin/proto.tab.keystream | Bin 4096 -> 0 bytes .../jvm/kotlin/proto.tab.keystream.len | Bin 8 -> 0 bytes .../caches-jvm/jvm/kotlin/proto.tab.len | Bin 8 -> 0 bytes .../caches-jvm/jvm/kotlin/proto.tab.values.at | Bin 263 -> 0 bytes .../caches-jvm/jvm/kotlin/proto.tab_i | Bin 32768 -> 0 bytes .../caches-jvm/jvm/kotlin/proto.tab_i.len | Bin 8 -> 0 bytes .../jvm/kotlin/source-to-classes.tab | Bin 4096 -> 0 bytes .../jvm/kotlin/source-to-classes.tab.keystream | Bin 4096 -> 0 bytes .../kotlin/source-to-classes.tab.keystream.len | Bin 8 -> 0 bytes .../jvm/kotlin/source-to-classes.tab.len | Bin 8 -> 0 bytes .../jvm/kotlin/source-to-classes.tab.values.at | Bin 97 -> 0 bytes .../jvm/kotlin/source-to-classes.tab_i | Bin 32768 -> 0 bytes .../jvm/kotlin/source-to-classes.tab_i.len | Bin 8 -> 0 bytes .../cacheable/caches-jvm/lookups/counters.tab | 2 -- .../caches-jvm/lookups/file-to-id.tab | Bin 4096 -> 0 bytes .../lookups/file-to-id.tab.keystream | Bin 4096 -> 0 bytes .../lookups/file-to-id.tab.keystream.len | Bin 8 -> 0 bytes .../caches-jvm/lookups/file-to-id.tab.len | Bin 8 -> 0 bytes .../lookups/file-to-id.tab.values.at | Bin 55 -> 0 bytes .../caches-jvm/lookups/file-to-id.tab_i | Bin 32768 -> 0 bytes .../caches-jvm/lookups/file-to-id.tab_i.len | Bin 8 -> 0 bytes .../caches-jvm/lookups/id-to-file.tab | Bin 4096 -> 0 bytes .../lookups/id-to-file.tab.keystream | Bin 4096 -> 0 bytes .../lookups/id-to-file.tab.keystream.len | Bin 8 -> 0 bytes .../caches-jvm/lookups/id-to-file.tab.len | Bin 8 -> 0 bytes .../lookups/id-to-file.tab.values.at | Bin 110 -> 0 bytes .../caches-jvm/lookups/id-to-file.tab_i.len | Bin 8 -> 0 bytes .../cacheable/caches-jvm/lookups/lookups.tab | Bin 4096 -> 0 bytes .../caches-jvm/lookups/lookups.tab.keystream | Bin 4096 -> 0 bytes .../lookups/lookups.tab.keystream.len | Bin 8 -> 0 bytes .../caches-jvm/lookups/lookups.tab.len | Bin 8 -> 0 bytes .../caches-jvm/lookups/lookups.tab.values.at | Bin 109 -> 0 bytes .../cacheable/caches-jvm/lookups/lookups.tab_i | Bin 32768 -> 0 bytes .../caches-jvm/lookups/lookups.tab_i.len | Bin 8 -> 0 bytes .../compileKotlin/cacheable/last-build.bin | Bin 18 -> 0 bytes .../shrunk-classpath-snapshot.bin | Bin 692 -> 0 bytes .../local-state/build-history.bin | Bin 31 -> 0 bytes .../compileJava/previous-compilation-data.bin | Bin 23846 -> 0 bytes .../main/java/{Main.java => MainFuture.java} | 2 +- .../src/main/java/coroutines/Main.kt | 4 ++-- ...WikiGameDumbImpl.kt => WikiGameCoroImpl.kt} | 2 +- .../wiki/WikiRemoteDataSourceImpl.kt | 2 +- .../main/META-INF/executor.kotlin_module | Bin 24 -> 0 bytes .../caches-jvm/inputs/source-to-output.tab | Bin 4096 -> 0 bytes .../inputs/source-to-output.tab.keystream | Bin 4096 -> 0 bytes .../inputs/source-to-output.tab.keystream.len | Bin 8 -> 0 bytes .../caches-jvm/inputs/source-to-output.tab.len | Bin 8 -> 0 bytes .../inputs/source-to-output.tab.values.at | Bin 274 -> 0 bytes .../caches-jvm/inputs/source-to-output.tab_i | Bin 32768 -> 0 bytes .../inputs/source-to-output.tab_i.len | Bin 8 -> 0 bytes .../caches-jvm/jvm/kotlin/class-attributes.tab | Bin 4096 -> 0 bytes .../jvm/kotlin/class-attributes.tab.keystream | Bin 4096 -> 0 bytes .../kotlin/class-attributes.tab.keystream.len | Bin 8 -> 0 bytes .../jvm/kotlin/class-attributes.tab.len | Bin 8 -> 0 bytes .../jvm/kotlin/class-attributes.tab.values.at | Bin 52 -> 0 bytes .../jvm/kotlin/class-attributes.tab_i | Bin 32768 -> 0 bytes .../jvm/kotlin/class-attributes.tab_i.len | Bin 8 -> 0 bytes .../jvm/kotlin/class-fq-name-to-source.tab | Bin 4096 -> 0 bytes .../class-fq-name-to-source.tab.keystream | Bin 4096 -> 0 bytes .../class-fq-name-to-source.tab.keystream.len | Bin 8 -> 0 bytes .../jvm/kotlin/class-fq-name-to-source.tab.len | Bin 8 -> 0 bytes .../class-fq-name-to-source.tab.values.at | Bin 100 -> 0 bytes .../jvm/kotlin/class-fq-name-to-source.tab_i | Bin 32768 -> 0 bytes .../kotlin/class-fq-name-to-source.tab_i.len | Bin 8 -> 0 bytes .../jvm/kotlin/internal-name-to-source.tab | Bin 4096 -> 0 bytes .../internal-name-to-source.tab.keystream | Bin 4096 -> 0 bytes .../internal-name-to-source.tab.keystream.len | Bin 8 -> 0 bytes .../jvm/kotlin/internal-name-to-source.tab.len | Bin 8 -> 0 bytes .../internal-name-to-source.tab.values.at | Bin 151 -> 0 bytes .../jvm/kotlin/internal-name-to-source.tab_i | Bin 32768 -> 0 bytes .../kotlin/internal-name-to-source.tab_i.len | Bin 8 -> 0 bytes .../cacheable/caches-jvm/jvm/kotlin/proto.tab | Bin 4096 -> 0 bytes .../caches-jvm/jvm/kotlin/proto.tab.keystream | Bin 4096 -> 0 bytes .../jvm/kotlin/proto.tab.keystream.len | Bin 8 -> 0 bytes .../caches-jvm/jvm/kotlin/proto.tab.len | Bin 8 -> 0 bytes .../caches-jvm/jvm/kotlin/proto.tab.values.at | Bin 253 -> 0 bytes .../caches-jvm/jvm/kotlin/proto.tab_i | Bin 32768 -> 0 bytes .../caches-jvm/jvm/kotlin/proto.tab_i.len | Bin 8 -> 0 bytes .../jvm/kotlin/source-to-classes.tab | Bin 4096 -> 0 bytes .../jvm/kotlin/source-to-classes.tab.keystream | Bin 4096 -> 0 bytes .../kotlin/source-to-classes.tab.keystream.len | Bin 8 -> 0 bytes .../jvm/kotlin/source-to-classes.tab.len | Bin 8 -> 0 bytes .../jvm/kotlin/source-to-classes.tab.values.at | Bin 97 -> 0 bytes .../jvm/kotlin/source-to-classes.tab_i | Bin 32768 -> 0 bytes .../jvm/kotlin/source-to-classes.tab_i.len | Bin 8 -> 0 bytes .../cacheable/caches-jvm/lookups/counters.tab | 2 -- .../caches-jvm/lookups/file-to-id.tab | Bin 4096 -> 0 bytes .../lookups/file-to-id.tab.keystream | Bin 4096 -> 0 bytes .../lookups/file-to-id.tab.keystream.len | Bin 8 -> 0 bytes .../caches-jvm/lookups/file-to-id.tab.len | Bin 8 -> 0 bytes .../lookups/file-to-id.tab.values.at | Bin 55 -> 0 bytes .../caches-jvm/lookups/file-to-id.tab_i | Bin 32768 -> 0 bytes .../caches-jvm/lookups/file-to-id.tab_i.len | Bin 8 -> 0 bytes .../caches-jvm/lookups/id-to-file.tab | Bin 4096 -> 0 bytes .../lookups/id-to-file.tab.keystream | Bin 4096 -> 0 bytes .../lookups/id-to-file.tab.keystream.len | Bin 8 -> 0 bytes .../caches-jvm/lookups/id-to-file.tab.len | Bin 8 -> 0 bytes .../lookups/id-to-file.tab.values.at | Bin 100 -> 0 bytes .../caches-jvm/lookups/id-to-file.tab_i.len | Bin 8 -> 0 bytes .../cacheable/caches-jvm/lookups/lookups.tab | Bin 4096 -> 0 bytes .../caches-jvm/lookups/lookups.tab.keystream | Bin 4096 -> 0 bytes .../lookups/lookups.tab.keystream.len | Bin 8 -> 0 bytes .../caches-jvm/lookups/lookups.tab.len | Bin 8 -> 0 bytes .../caches-jvm/lookups/lookups.tab.values.at | Bin 109 -> 0 bytes .../cacheable/caches-jvm/lookups/lookups.tab_i | Bin 32768 -> 0 bytes .../caches-jvm/lookups/lookups.tab_i.len | Bin 8 -> 0 bytes .../compileKotlin/cacheable/last-build.bin | Bin 18 -> 0 bytes .../shrunk-classpath-snapshot.bin | Bin 692 -> 0 bytes .../local-state/build-history.bin | Bin 31 -> 0 bytes .../compileJava/previous-compilation-data.bin | Bin 23848 -> 0 bytes .../main/java/{Main.java => MainExecutor.java} | 2 +- 241 files changed, 10 insertions(+), 16 deletions(-) create mode 100644 wikigame/.gitignore delete mode 100644 wikigame/.gradle/7.6/checksums/checksums.lock delete mode 100644 wikigame/.gradle/7.6/dependencies-accessors/dependencies-accessors.lock delete mode 100644 wikigame/.gradle/7.6/dependencies-accessors/gc.properties delete mode 100644 wikigame/.gradle/7.6/executionHistory/executionHistory.bin delete mode 100644 wikigame/.gradle/7.6/executionHistory/executionHistory.lock delete mode 100644 wikigame/.gradle/7.6/fileChanges/last-build.bin delete mode 100644 wikigame/.gradle/7.6/fileHashes/fileHashes.bin delete mode 100644 wikigame/.gradle/7.6/fileHashes/fileHashes.lock delete mode 100644 wikigame/.gradle/7.6/fileHashes/resourceHashesCache.bin delete mode 100644 wikigame/.gradle/7.6/gc.properties delete mode 100644 wikigame/.gradle/buildOutputCleanup/buildOutputCleanup.lock delete mode 100644 wikigame/.gradle/buildOutputCleanup/cache.properties delete mode 100644 wikigame/.gradle/buildOutputCleanup/outputFiles.bin delete mode 100644 wikigame/.gradle/file-system.probe delete mode 100644 wikigame/.gradle/vcs-1/gc.properties delete mode 100644 wikigame/build/classes/kotlin/main/META-INF/wikigame.kotlin_module delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i.len delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i.len delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream.len delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.len delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream.len delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.len delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i.len delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream.len delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.len delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.values.at delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i.len delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/counters.tab delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i.len delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.len delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab_i delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab_i.len delete mode 100644 wikigame/build/kotlin/compileKotlin/cacheable/last-build.bin delete mode 100644 wikigame/build/kotlin/compileKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin delete mode 100644 wikigame/build/kotlin/compileKotlin/local-state/build-history.bin delete mode 100644 wikigame/build/tmp/compileJava/previous-compilation-data.bin delete mode 100644 wikigame/build/tmp/jar/MANIFEST.MF delete mode 100644 wikigame/completable-future/build/classes/kotlin/main/META-INF/completable-future.kotlin_module delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i.len delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i.len delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream.len delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.len delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/counters.tab delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i.len delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.len delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab_i delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab_i.len delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/cacheable/last-build.bin delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin delete mode 100644 wikigame/completable-future/build/kotlin/compileKotlin/local-state/build-history.bin delete mode 100644 wikigame/completable-future/build/tmp/compileJava/previous-compilation-data.bin rename wikigame/completable-future/src/main/java/{Main.java => MainFuture.java} (94%) rename wikigame/coroutines/src/main/java/coroutines/repository/{WikiGameDumbImpl.kt => WikiGameCoroImpl.kt} (98%) delete mode 100644 wikigame/executor/build/classes/kotlin/main/META-INF/executor.kotlin_module delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i.len delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i.len delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream.len delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.len delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/counters.tab delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i.len delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.len delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab_i delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab_i.len delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/cacheable/last-build.bin delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin delete mode 100644 wikigame/executor/build/kotlin/compileKotlin/local-state/build-history.bin delete mode 100644 wikigame/executor/build/tmp/compileJava/previous-compilation-data.bin rename wikigame/executor/src/main/java/{Main.java => MainExecutor.java} (94%) diff --git a/wikigame/.gitignore b/wikigame/.gitignore new file mode 100644 index 0000000..12c29f7 --- /dev/null +++ b/wikigame/.gitignore @@ -0,0 +1,4 @@ +build* +build/* +.gradle/* +.idea/* \ No newline at end of file diff --git a/wikigame/.gradle/7.6/checksums/checksums.lock b/wikigame/.gradle/7.6/checksums/checksums.lock deleted file mode 100644 index 1e52391c353b4648b2a5d8e062c9d5a22ce3120a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17 ScmZS1NZgy1rY&vH00jUh5dz-; diff --git a/wikigame/.gradle/7.6/dependencies-accessors/dependencies-accessors.lock b/wikigame/.gradle/7.6/dependencies-accessors/dependencies-accessors.lock deleted file mode 100644 index 9af0f7bb955708eb565113fef24a861a0502694c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17 ScmZR!6yLEfwI!IH0SW*m_yYX^ diff --git a/wikigame/.gradle/7.6/dependencies-accessors/gc.properties b/wikigame/.gradle/7.6/dependencies-accessors/gc.properties deleted file mode 100644 index e69de29..0000000 diff --git a/wikigame/.gradle/7.6/executionHistory/executionHistory.bin b/wikigame/.gradle/7.6/executionHistory/executionHistory.bin deleted file mode 100644 index c0090ef71fe691d5143fcafe11fc89ed410df17d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 109951 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 diff --git a/wikigame/.gradle/7.6/executionHistory/executionHistory.lock b/wikigame/.gradle/7.6/executionHistory/executionHistory.lock deleted file mode 100644 index 530e9a49fed3877bbe333dd4b6436d5e63c3bcd7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17 TcmZQptX1)v6EGu$0RqGUBOC(% diff --git a/wikigame/.gradle/7.6/fileChanges/last-build.bin b/wikigame/.gradle/7.6/fileChanges/last-build.bin deleted file mode 100644 index f76dd238ade08917e6712764a16a22005a50573d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1 IcmZPo000310RR91 diff --git a/wikigame/.gradle/7.6/fileHashes/fileHashes.bin b/wikigame/.gradle/7.6/fileHashes/fileHashes.bin deleted file mode 100644 index bff2d22859b2dfdeab633034f01e94d770590497..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31797 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 diff --git a/wikigame/.gradle/7.6/fileHashes/fileHashes.lock b/wikigame/.gradle/7.6/fileHashes/fileHashes.lock deleted file mode 100644 index 6bf83d91a0ab7aab1323f713652ab5ddd3de58c3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17 VcmZSfdZOf?cHit30~jz`0RS-$1VaD- diff --git a/wikigame/.gradle/7.6/fileHashes/resourceHashesCache.bin b/wikigame/.gradle/7.6/fileHashes/resourceHashesCache.bin deleted file mode 100644 index fe0eda905f91f054e4d47de4387b687636589e5f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19857 zcmeI(`#02i9LMoVag^&UgUBssYbqj28CuL%=R3ooIw4|0=(4+#R4!4*rI_SWwvcO~ zHn-yxLXKpuPAcshJ46?9ZMBt@MXfpC?`J#f<1gsEzvm3!^YA*~bG}dGC*RpbqiHCA zrViSdgYo4Q&Y%DkfC5ke3P1rU00p1`6o3Ly017|>C;$bZ02F`%Pyh-*fv=^&j+q-- zMBa>sp_JrA=_rk6B0qD&jB|H9Jf1eyOa7Sah5mnV=7|i0$4avy-R{PJ{?_%wE*K?y-{D-7-t&!hO6Dn1^EbS(pQ;EE> zrX;Lg`2=-e_9u}yy_U^W*v8&V?YAO-KqN7&I)$q!7bE}kw5T}9JTI1Xdp`0`XN$0N zy%83q+c_eC_Of;N)H;;|q!T{K`-NtG8EI{9)IJdTU}}9e$IWzrbgnk?VR1$!E&m9I z@@C{pi%bfN1`CELzw)1Va#CYWk7oVXO=U#GLg zpK@d5yjSVYw9MoQ(z!#(o%^H9uSoCPNjlMje3$*&$l|yO5$Sdl$UQ7S8;XpgOi^|A5i;L3O-4#E~W`c9+Gr`nMV_zDG} z02F`%Pyh-*0Vn_kpa2wr0#E=7KmjNK1)u;FfC5ke3P1rU00p1`6o3Ly017|>C;$bZ z02F`%Pyh-*0Vn_kpupE%z-;FB7SFusl9#f4ueDU}yHvxa4IcLr?wm`XL7o3EUX3_^ z!{@dwi0G+NRGU(hJbyfE(S7^=C)%~)d+CPS$*s{uFuusl>p7&;!tJ9gv0AyoPW|{| z3H!WM`F8`Z4evkNgg&~w3tuoTIjP3RGGc?ZsdtR_c-_Yr2aJelZgo-y?`Hv+m_o%J9P6?to`mX@eo0BPN0P!qlt7J@&Wd6N*Nf z8zSYCZsCgwkxkXgV)`IIY2bzNi<}&M(H61F$luN(Nu94(#Ryl7!xz4jLv_i!&7XT# zs8{e0osGg5i)DZ1zNJ-$fs+1?5igxkZ=Rse zhpXiK z^Jn!)j7)fCQ#P&=Cwo1TEt4;UFS;&oH9WheecD#rS5Rvz$i^2PYGu;lAyOgD0`*c` zOY=Dvue-+l>s>6ZvNC??5D6mm@oN-0gt|1{&i>3~xQ72MUA6&V+?5U7=3Tvm%dBS& zdT!fcj4wPLlY1U!dgoeqtd@&*Iy8+hxUpI7l|D|1J8!wMRq{ROc#rjo<*hbr_lXpy z|MK@+r(B3%P`h}B?>tE8=&haj+ci*lyFUIfba#cgEm0|CS@N1+Gnia~b zj^+)Fj0msA=f~iSgPwbe>yL5t3lH~NY%N_N#1}CRVjr4@FY5`9X~PSund5ic^X;W5 l+Wt^8_vWg=6SWCV_%;6KK93p`youSYdosQ~L@7YB_!oKgSjqqZ diff --git a/wikigame/.gradle/7.6/gc.properties b/wikigame/.gradle/7.6/gc.properties deleted file mode 100644 index e69de29..0000000 diff --git a/wikigame/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/wikigame/.gradle/buildOutputCleanup/buildOutputCleanup.lock deleted file mode 100644 index f81f048e3794d5e650a61782d6aac70fad8dd060..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17 UcmZR6wC+HT<^sD93=j|k06dNb3jhEB diff --git a/wikigame/.gradle/buildOutputCleanup/cache.properties b/wikigame/.gradle/buildOutputCleanup/cache.properties deleted file mode 100644 index 971117e..0000000 --- a/wikigame/.gradle/buildOutputCleanup/cache.properties +++ /dev/null @@ -1,2 +0,0 @@ -#Sat Sep 02 19:45:30 MSK 2023 -gradle.version=7.6 diff --git a/wikigame/.gradle/buildOutputCleanup/outputFiles.bin b/wikigame/.gradle/buildOutputCleanup/outputFiles.bin deleted file mode 100644 index 40ae3641f1f9fd8d9237b8370eaf272ad697043b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19919 zcmeI%eNfYN9Ki7*>H?Mo2VzKYC&<&lNFXBuDuD z5)WaZl*mKaL6Rvd7z!Myz=e1`OTd|OiOk~|jr)E-^Sb@BTW9BWpWSWjUi*B%zy01D zzklY%Vy$^;k=|HOZ~9N4;xjCO1+V}XzyeqR3t#~(fCaDs7Qg~n01IFNEPw^D02aUk zSm6Isz+ZMEn&f2G*eqLmqMgKI*>Pk~d_GkdJ80)hd&$efarpfp%f~!lcQUPrxL_A} zwl7yu*mv z=}xv|Q-4wJ)4fL}h0S!H2?HJi{I5mVt8&Bo|&G(vyyT8%v22J_UP$vh(f|7n%6y;Da=3O(*D`1zs6 z_hyZQuTbv>|K;|Rj($^vS>l3u@T;~ap{HC^Vg4d`%NGX@ybwOnPv={}Z9( zum0m?mQ|BAabXR3Z=lYl<@0rJ#F;$sKHv5r@uA{m;=F9|I~<-}p-sgE^(gScufq&W z-VLGO2L^a?*fL>DwQm@o%<~K2g|VxbwLh$JFeWZK1Aedal<8__k^W!sUk0D37#hx& zytR?e+k#K+P2YO_#$$Ej%pLIQwRRR=2IDStUPJE1rEC|^{4P501b#nbQGBf^U_Ei+ zXW%pDb<5_e*<9lM8SqD}!~Kt@*GcJowA|aGJ)~2u2dR64Klx2_b6Uy(y$&#Yz!z#4 z3a#2dr=JVI34HNxd1h<$pCe=+K`!`8;dQ@!{@V=oAaKrDmW!Dw07ElGn2Xx_&OKOH`OvDrin8R z;AW17o^1l>89L7fw~jj=sCMKWy^aaCf!lb0#o^eNr_=dC@HfVmtNW!`RS*|l0C&9o$)Dw;`bXoux~)>?SA!cQ4VZ)~d;a>+NB14;>F_q}g~UnHTxWy;?gY zY%!;bINt?)+jcL#gR}KFiSv@cz1`=o74+;{NnCgfd`ETofcd621LA^u@ZiM#9>XgJ z={};h;1Nk|UyCHa>vW%H@b`x+qqyUzf2I5AfJa@niw*7xo~LdKzIU>zyK$^Ui#Tr- zJnr5|UEvDdEyS60@OX{%Xo>q^2629d-1i%9GVba9ow(=(ctUd(FQ-##LtI!4zAwhh zW;Djql{oJk@MQbbf`O)^7wG=q%l$#@h_{z3{Tu~-;Hlpo^Ll6*Q%dF;eQ@~8VzKG9 ziA>-l7Qg~n01IFNEPw^D02aUkSO5!P0W5$8umBdo0$2bGU;!+E1+V}XzyeqR3t#~( zfCaDs7Qg~n01IFNEPw_6O#yq^Vh!0{ZRx)Bu<9QogXdgSd(Voi6h-mem6=gorHrVy y^Rru}+Rmz->3?~wXZH@D|Fcl-+?83S%#3P%6jv#V;?b3vQCy{rsJ64xtNsQg9UFlF diff --git a/wikigame/.gradle/file-system.probe b/wikigame/.gradle/file-system.probe deleted file mode 100644 index 596c735e6607c4f7d6753d0f8c36cc5ef786307a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 PcmZQzVC)Jzof!xK2b=|Nqwj8mjy2|NlfF{pAP5JwT~ZFd71*Aut*OqaiRF f0;3@?8UmvsFd71*Aut*OqaiRF0;3^7LtWw9r zZhN{EdzDcP4RvfB-TBGXd*cQQ9H{eG-BSI~;Z+)EDv#}S`wUqzxCtoGYkYE009U<00Izz00bZa0SG|g G9|CUyF_B0B diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len deleted file mode 100644 index 6fdc033695a244e08b264dbc888a15302bbc4d12..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 McmZQz00GAN005}~p#T5? diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len deleted file mode 100644 index 817b326d9eb94f6a38f5e047201a69ab944ef476..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 LcmZQz0D~O>0Kfpb diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at deleted file mode 100644 index b8981a08af11cb362c2ddea544d5d4b2ed3c985d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2131 zcmcJQO-_SA7=~v-@4&R8-}_bC;-x70LF56|l>NBuDtNkn4E< z=4v(#!i$CP;QNBI7)OjK1qvr3XO!cVl#fhMo?}TQPDKn1Zwru5OUe^9u3z{2gPf^I zGs3Ch4Kgr*bQDNR7<~rWKrg#OSF_;!Y_Xo>N1D(hNnzaR2+R2k1}|vRmDE<}mFmrg z`LOiUR6A_aEOiH}5bfoyd%*@<+uI0jbdz0|hfrU<4=NK}{Veg;7_aT{V2(VP(DxDA z^@%wlQNpSkIhA^6l-U*=nxzjW_tQe1`|7`zsjs#9xVO3^S8Y{u+7h+b{zn{4-0KKw Zw^{vX`#sCX-d@+8i2;1tUO!009C72oNAZ zfB=D9fm=*>+3=P7X-I$o0RjXF5FkK+009C72oNApTHqKL_Pz0<^dScb5FkK+009C7 P2oNAZfB*pkH4*p&^<)l! diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i.len deleted file mode 100644 index 131e265740f37d77b7c4a3676d2a7704ca3e4a29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 McmZQz0D%Su009U9fdBvi diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab deleted file mode 100644 index 43b5a468129b08a13bd75dba30f1ecb9c28144bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmeIu(FVd$9LMp0JwPI*7wEo=UZDG~qPw184>3g#5hEg+h!K%ujEFdIvR7Drk2>tC z2gvWw_BlIeHonQ^+A^l&Z(-V>MZaOTVEJPFPW>H@%wJ*r+2H$7-w)@%bbP02n$?cjw#;I;RQ=PV~?MnaEuww@rX-2V2XQmxWfv!IBc42aEb}WxJEv!Q2`ZD X0ToaI6;J^cPyrQC0TobzzbWtr6H`@d diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream deleted file mode 100644 index b5e10556d60a58c712a8bd65009ef6412b1572fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmeH@!4APd5QaTOFC2s@5n{zFaCN}NdBa2|ZFiep4m`cI3A@^@iu1q6nSbY-`J!C2 zx(XwW$n=>~v1OI?Lq)OCSuPc8H3+t2ONM324>D0Tu#*?+hKdEvjv70TId0B);M(H* z8=3oBo|3cxO{+sb+m1GC33|w0Fk0RfH@6&W@+IV9YWE*G;rC$&vbk24mepawl!LE+ t%X@naLqE!EUpvfO6OO-V&wA_*9t^+$48Q;kzyJ)u01UtY48XwO2A<+s1B3to diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len deleted file mode 100644 index 88a2818c6f8d6e122f8031e84de5972d8268029a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 McmZQz00E{o006iEuK)l5 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len deleted file mode 100644 index 14f7c061cc4bef2fdb72d8ebd5cc8c9a23a22d1b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 McmZQz00Bk`001HY8UO$Q diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at deleted file mode 100644 index c1f99d4026680e243c9b16ea568dda619bca65f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 106 zcmdOA@JLNeNi9+cN=?o$N>OmjFH#6dEh^3|E=kQR@klJr@J%cTOUx-v4KB$qN=#2> JWMCi<0RXKe5*Gjf diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i deleted file mode 100644 index edbb2cf419ac44d71414bf7d0103f26bd1b6654b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32768 zcmeI%KPZG@90%}MN=8MLC=-LhKsMVYqYZ&6kP~ zHjn@T0x1_bihKv9{r8l|6psJ_0+kbp?|myz&C`_|Xc7Se1PBlyK!5-N0t5&UAVA

E_nzLAV7cs0RjXFWJ%yH%D#^t zA5^>ZSsXAs{B>3BbId0|fB*pk1PBlyK!5-N0%;Ohi!k}uiJLTKN@JGG2sN4CUrJ*( znFtUdK;ZuZ*D<0n-nH=mNhS~=K!5-N0t5&UsJ=icju;#$d{+M?C)9#KK0-EKbQk}c z^)WUc&Mcn)b-#TCvLvt@WxMyL{9c}=m#!-T0t5&UAn;4zBko4-a=pJ6-4G}v@Eq%X zJN>I=9$O|*Qv%zOcKr0Jy{1A7OMpNo1dgL+=g{(8Cdw*FfIwXe+(xUOwvCgzET~v1OI?Lq)OCSuPc8H3+t2ONM324>D0Tu#*?+hKdEvjv70TId0B);M(H* z8=3oBo|3cxO{+sb+m1GC33|w0Fk0RfH@6&W@+IV9YWE*G;rC$&vbk24mepawl!LE+ t%X@naLqE!EUpvfO6OO-V&wA_*9t^+$48Q;kzyJ)u01UtY48XwO2A<+s1B3to diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len deleted file mode 100644 index 88a2818c6f8d6e122f8031e84de5972d8268029a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 McmZQz00E{o006iEuK)l5 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len deleted file mode 100644 index 14f7c061cc4bef2fdb72d8ebd5cc8c9a23a22d1b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 McmZQz00Bk`001HY8UO$Q diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at deleted file mode 100644 index 816b5e3d3362b61d665cdcac30cd86c0d62d3edb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1228 zcmd6l%?g4*5P7Z_ zq~Qd_3zcHdH$rB;%ygKF>Zsb#V?&#+hHBb$Yv_cHZG`s~(sK?;mVd0<=10u4_Wy3Y kEjD1jjq_P#;&6kP~ zHjn@T0x1_bihKv9{r8l|6psJ_0+kbp?|myz&C`_|Xc7Se1PBlyK!5-N0t5&UAVA

E_nzLAV7cs0RjXFWJ%yH%D#^t zA5^>ZSsXAs{B>3BbId0|fB*pk1PBlyK!5-N0%;Ohi!k}uiJLTKN@JGG2sN4CUrJ*( znFtUdK;ZuZ*D<0n-nH=mNhS~=K!5-N0t5&UsJ=icju;#$d{+M?C)9#KK0-EKbQk}c z^)WUc&Mcn)b-#TCvLvt@WxMyL{9c}=m#!-T0t5&UAn;4zBko4-a=pJ6-4G}v@Eq%X zJN>I=9$O|*Qv%zOcKr0Jy{1A7OMpNo1dgL+=g{(8Cdw*FfIwXe+(xUOwvCgzET}0!+`-9fB_hQ0T_S*7=Qs7fB_iz+rSG_MFT|u diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len deleted file mode 100644 index 88a2818c6f8d6e122f8031e84de5972d8268029a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 McmZQz00E{o006iEuK)l5 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len deleted file mode 100644 index 14f7c061cc4bef2fdb72d8ebd5cc8c9a23a22d1b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 McmZQz00Bk`001HY8UO$Q diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at deleted file mode 100644 index 816b5e3d3362b61d665cdcac30cd86c0d62d3edb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1228 zcmd6l%?g4*5P7Z_ zq~Qd_3zcHdH$rB;%ygKF>Zsb#V?&#+hHBb$Yv_cHZG`s~(sK?;mVd0<=10u4_Wy3Y kEjD1jjq_P#;B+qSXC4uKV2Sbbj9V`=04^x=C$Pk@yiHK!5-N0t5&UD3ZWO^gN7?wHB#PO`Zj& zB5&^PzBA9UB_DSl8#FF&45YQlRuoSk&W@zjua^LU^aXBXg!bO~#`GsK0RaM!L2%LC zvP6PFAq8F{eDU(8uaF(G2@oJafWS`zr*UDkbFlfR>&};!z<7*X)zGw4T2q^rKzR!6 z#@Y=XU8#MCE>Cq^6Cm(ipeB9YP;`NVXk6WEc`kafLIMN`5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0tDhu(n)gNJ5r5;009EI3S33N)A8^`t~s73K%jgDW@7d1 z{(H831#JEw1y*9I&${~U|G1l-2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5Fk)W F0$+YlGCBYN diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len deleted file mode 100644 index 131e265740f37d77b7c4a3676d2a7704ca3e4a29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 McmZQz0D%Su009U9fdBvi diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab deleted file mode 100644 index c691266213b4bd9024ef1107f872a2a5c8d8989a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmeH@F$+Oa7={m%Nd}aO&B$P3v&djlHk(2D5u*GHf8Y*wga2@+8-p?^MY*|=B=UMs z+`5xpy>FfKob!F>-qU%etwqu>X*-2UeHMk7F(WR)*h=&aTgHwswpaabqV=%F+;pLg3U6d8~K8IS=PkO3Kx0U3}18IS=P_-6xe D3dU2| diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream deleted file mode 100644 index 788ff54259ae7dbb3ffd11084a593ac263111658..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmeH_y$*sf6h?glCl(!yMl?pFjjy1qgSt4HMsG~h(vlVieR_dJTA}qB-M$ zYl~k}(C-6%aFK&n)l2@zmbUH)I>@m%TJ#EAMy1SUOUS|0`rjC5Ww9%mSV;qNrl?y6&$uZMSaiN;?>7D>NYrLh8l{rISWG1`;ojNlj~-#hvYL zY=6M`5BLLk)tCGYAZ;%|yh42i5)!=OC4#*|NPM3=+esQH4V|khqLrGvoPB5C-S@fA z^W3G#N~W=CI#cUr*>*OkZrIM$Ez@x=*E6eL$#A!C8oPIl%AUF5*^aSg{+MI}AiX!2nw9rEZnbnMzqc5c=$<;xv7g@Fx-cfpzKw%#W z`KKw+|UkU&=F^^v`x4I(?VBx}P+8PXA?qe$~e$4XBV>jS}~(bqys zQMK&8Jb|H@WFu?4wpI0tj^PyV+M8yjxMo#%mT|4eHO=ZGWjxEPn8=)SO~*1S)+58S z?CLeU>Uz#z8AE&1aCS_Gy}7nydljqtd9mTfBHA~ds!=I!w5`9)-k*DC?K9)PQLGr% zt>T8~Sk zG$yvUjUFr85ZN^h8&f=6yf0H9IF@J5Y?zf#abwD*RJQlL-93*jw&;vmE!&&uZ1EaB z(nbBZsKj)ZnJUKey6KkLD=n&T;-X{iVkTUFjOlh!vdpqG!F1q_GxP+biuq&818c|H zGVYq+B=Mq*y)hD+MId@EeC2U6&q(eoX+#KpKa$6R*D=A6X@_=vO$P0Uh zbq7{0DNiMIQuL{=tI5^8rWA6zqRTp3Sx^@;us#}u?CJnFVF`9d_S;8RIi~d^tD%St zRYyvuDdE!kkTAhl?|gWGB>;Yc=(uZM|()O~>%e%}z#5 z%t1{y$5d7?EU2b5b`@q6y#myp6eUotylqwL-kS`pBT>xG&41M5i4Ee(;`#p4W3u!n zXaUn=b1kZd#&})axXd!O+E6*a-bww?hI{T4glY!&cbcTi{+RU*uAg+M_4({kkoE`$ zflyGL@)*SNwaH+H&Aefx$Q~$Ch1{}`9l?c_zLdZT5@(V)lLb-;PK>^s=SmgO;p|#c zIiUO-2tXPt4gf$oUP~7MB0XmXfQER(koKTYJ-mhB3zQAy@MeP|Ma%5V!|3!#gel(w zn>lg<(x|(JgLRk6*^3dYchfS%Tfn+Pio8{;n};F~o0fRkQHy_u7JoE!+r~Tlt9?BX zYWbxmIIu`Age%q0y)^lWt2e^smS$ggAydKH)ZmHG>c#z&*8a$(@JA*lSLW;dkv`0f z%GYVx_e#=yG8OKGKu8*&^txNLkfrPSJZeKo!p*zpUBWIO77q`)Mfj6>4 z%SkJIoVZJ~5x6vao<+Wu>&4*E4EiQfYtwgU_y{mPaA#`QkL%2^E_7$UkIkLA)LLe7 z_%v-*94;4scC%x1DQflQDviOrX*+&rE>0&d%89u+zX-^^bo!7R)N|m8@a$y~eya#z zdTT|5w=o}YeH@74-SNY1wDDzx!&Ha1<`C+=J=1x(Vw86{%o_NX`6MX*e=sfw_bwcX z|2yXnV&mN9CeAf#E)Liot?Q6@|8z6)E*~ad<50$cy`x9+jD4rdzP|+fRWZxIB2IjuJc`X-`RDeg@+P_bth`vw&CvG#%D zi3fk{4Z$A{BVvgC^!nJ3n)E|I+SYK{Ktt$9mya9yb>BAj53%uZwvE!_U}1YDha7y? z%^aMK(xk%`n z@ygM%j01}usXs*Gx801yD^W;nu=5yj*wJ{Nq3~2uc!B$Md3=(!Ch(u(CHT0=F7xca DXifwk diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i deleted file mode 100644 index 9037815edbe77417c578dc7b9d793456a7a8c9be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32768 zcmeI&F-RL>6bJANEgwQ{y%ZO*&fTOG1i?kAgOnx&3Z)bZf({}M zQbD_vYN4Q$79B(!q?D@Ap>NC*5=gu==6BO^-*@l--fucSE_s}EB`yL42oNAZfB*pk zDGA&}&e_Y^;gsUUv{+z1>b?1MI@;p0ZC`FbCg?AJn#^jD)d*hrvNV%bzFYzXvKKgs z7M>QD`?K#v2LuS52f>f=p?4$*+@-)(6o32k_}N`%s7-(X0RjYS34D!(&!ba=wbngv zFM(Il?xVuMdV6)PTLPUaun}VyM#eHbhwe;uQxhOiEzp}wlIbTOo>xC}-?+fX*qSTv z>^1&|odgIFAVA>$33SKzz^}RA6Zfw(9T6ZvfB=E!1y-U&<=de1^5!X3AdtGib|k*v z9J)+BSRerc1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009E=lXQ|C6=!--5FkLHS%JeS zaIyR1b+dK6Pk=z@3M|IxrLDiE&J{5ELlmgQP`7>gwTC#HnFtUdK!89!fqa}h{X6)6 iU2mUt0t5&UAV7cs0RjXF5FkK+009C72oNBUhQNPYIW^}1 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len deleted file mode 100644 index 131e265740f37d77b7c4a3676d2a7704ca3e4a29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 McmZQz0D%Su009U9fdBvi diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab deleted file mode 100644 index f12eff4a8d8b5c6d4950d185183b802ccabc8bec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmbR3vzw0r2-rac39ha-|Gy8UJ%O|&(9ny2|NoBz(iT7(C_D;ALtr!nMnhmU1V%$(Gz3ON ZU^E0qLtr!nMnhmU1V%$(Gz5qY0RU+CA}as@ diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream deleted file mode 100644 index 944b47d9e97d4e1c405c86b53f35d3722f762dc2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmeIuF$=;l5QbrYOlNQCqJtn>2Su<3!BLJH5Cqze9fTTyX6aQw2r_mL;hO0(On zmWNZZHW{T@QN!Zt%6FzVi0>$Jq$ZqgO(6eXDUaghJ8NuegHOY+=h`E$^`8SHJP1Gl0uX=z1Rwwb2tWV=5P-lx1fE%t Bkw^dl diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len deleted file mode 100644 index 6fdc033695a244e08b264dbc888a15302bbc4d12..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 McmZQz00GAN005}~p#T5? diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len deleted file mode 100644 index 817b326d9eb94f6a38f5e047201a69ab944ef476..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 LcmZQz0D~O>0Kfpb diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at deleted file mode 100644 index 6aa951d304187bc60045a32931f2c1062a031507..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 852 zcma)(&q~8U5XScjJbBTBM2sSeF1~_-^q^2H=&=mVpu=u=!pug{qgNlm*EKEJV6xkI z&G*~y&%~MuLWNSyaKTa)w=BgJMM)!uI01dVhx!S8gO8B~Ua&H|HB*RIKwKjw&6WW&0gPkMXmbiQC8_%9p{;R zwNEqH`p}@fU&F$+1Du}rUH{5m{MiVY@9<{!lW*6{%PrF8hn#GI^10t;aI$A|w3$9b ltvM*#zI&4DE^+lgK40w19HuPR_xLS!K1y_jF2>n>nIDx4Ksx{c diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i deleted file mode 100644 index c2a36863843540ff5acb91b328645eaf1c76c55f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32768 zcmeIuy9okO5CzbO3Pyrm_({Y}P{G{T5^TZPXfYH_3=IvfKrBG4z#6Q8i2;1tUO!009C72oNAZ zfB=D9fqP7M+3=P7X-I$o0RjXF5FkK+009C72oNApTHqEJ_Pz0<^dScb5FkK+009C7 P2oNAZfB*pkH4*p&MYIlp diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len deleted file mode 100644 index 131e265740f37d77b7c4a3676d2a7704ca3e4a29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 McmZQz0D%Su009U9fdBvi diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab deleted file mode 100644 index fc0fd9ba773dbf5648ffd93e403d258651abb91c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmbR3vzw0r2$(K-}3cXWp>2a*In&q^aAjWi7;_ vkfAOU0;z>{{yMUMFEY0M(A34zaTK5c1t>rP3Q&Lo6rcbFC_n)U{8``ug!mf} diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream.len deleted file mode 100644 index 1ddb457a113791d5e7198fe8d8fbbeeccd3514d3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 LcmZQz00UP508Ic! diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.len deleted file mode 100644 index 01bdaa1da7d937c7e7d98e54ba912f88ab95c7f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 LcmZQz0D}nt0GI%g diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at deleted file mode 100644 index 7d49eac2136224b567093089a933ff4543a07249..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 324 zcmZwCF$%&!5QX7@SI~Y7wGdqK3Ko(=Ax6-8Fb^HF?uMC7p*OeFSV&mYfA42zmF1uc zVoF?sRAw8*6cA;N@G&R7?WsADYjKQ0=!(}UGfiM0t&rGzsNn35eQl=-VRHP0%u-N% xh8@zrTBPdGLLM8s)Gnp-LHbu*r|ir%|AHm730~2^VL7z;c8ByN8>hbe>fhUf t*IXh%fB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oTsnU;t~M1)~4} diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i.len deleted file mode 100644 index 131e265740f37d77b7c4a3676d2a7704ca3e4a29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 McmZQz0D%Su009U9fdBvi diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab deleted file mode 100644 index c2c27d0ab7d6de173c8a8774b84e1b0b6b9a0e22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmbR3vzw0r2-rac3QRZa l(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S``90swtOW;Xx; diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream.len deleted file mode 100644 index 3a3075b1c7bfe5be9724a142e408d7022e61c988..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 McmZQz00Blm000;O5C8xG diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.len deleted file mode 100644 index 817b326d9eb94f6a38f5e047201a69ab944ef476..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 LcmZQz0D~O>0Kfpb diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.values.at b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.values.at deleted file mode 100644 index 2b792d5392ce648c1c6b5fc25f152586bae734b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 387 zcmd6g!3hFE5Ck^`jbI~KK|>JqK7x2~|JG}CaGg13M-Zd;p%L86cTrWV)Da^+pLj7J z^UgdU=}lTtqeHtLFb$|r_F;}IH)(yhsG_gZ=z=P5gqRl5pet(GQ|Snf{g2a^Y4MfH Q)*cfa=Q=Mm>;C7`2Z{@m!~g&Q diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i deleted file mode 100644 index 816f809778fa3573f6164b16d8abd446b7afc807..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32768 zcmeIuAr1mD6a>&F2rfWyBq$Jg9BvPQ#d8jVgaiQ&91>9I^=Je~;20Rb+ygYtZt|*{ zikaz4{nSei0RjXF5FkK+Kz4y=BvzlpH+!%^0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C81dh?Mp8x6sRVoM&AV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV8o+0=w8Ux~yI;nq&$A0t5&UAV8p~ zz%AMq?`l%CR9R;QuCaW2nr%A!0mBJ21h#QsKI&oP$&~;B0t5&UAV464z&SF;gZ({2 Nln4R@2oNYJ@CT~65aR#< diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i.len deleted file mode 100644 index 131e265740f37d77b7c4a3676d2a7704ca3e4a29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 McmZQz0D%Su009U9fdBvi diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/counters.tab b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/counters.tab deleted file mode 100644 index 3d952e7..0000000 --- a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/counters.tab +++ /dev/null @@ -1,2 +0,0 @@ -7 -0 \ No newline at end of file diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab deleted file mode 100644 index 60f72c74f664645961544e8dd5a6820321a40f5f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmbR3vzw0r2-rac3n`#^ddkd_1*x&cVX0qIph8YnypMnhmU1V%$(Gz3ONU^E0qLtr!n WMnhmU1V%$(Gz3ONU^E1X3;_TDtRut# diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream deleted file mode 100644 index 944b47d9e97d4e1c405c86b53f35d3722f762dc2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmeIuF$=;l5QbrYOlNQCqJtn>2Su<3!BLJH5Cqze9fTTyX6aQw2r_mL;hO0(On zmWNZZHW{T@QN!Zt%6FzVi0>$Jq$ZqgO(6eXDUaghJ8NuegHOY+=h`E$^`8SHJP1Gl0uX=z1Rwwb2tWV=5P-lx1fE%t Bkw^dl diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len deleted file mode 100644 index 6fdc033695a244e08b264dbc888a15302bbc4d12..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 McmZQz00GAN005}~p#T5? diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len deleted file mode 100644 index 817b326d9eb94f6a38f5e047201a69ab944ef476..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 LcmZQz0D~O>0Kfpb diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at deleted file mode 100644 index 25454f32baadef9abd2a46657e796ddb67161bb6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 91 zcmdOA@JLNeNi9+cN=?o$N>OmjFH#6dEh^3|E=kQR@klJr@J%cTOUx-v4KB$qN=#2> XVE_Rz$p|Kyz$7!6WC4?`V3G|0pe7PE diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i deleted file mode 100644 index c2a36863843540ff5acb91b328645eaf1c76c55f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32768 zcmeIuy9okO5CzbO3Pyrm_({Y}P{G{T5^TZPXfYH_3=IvfKrBG4z#6Q8i2;1tUO!009C72oNAZ zfB=D9fqP7M+3=P7X-I$o0RjXF5FkK+009C72oNApTHqEJ_Pz0<^dScb5FkK+009C7 P2oNAZfB*pkH4*p&MYIlp diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i.len deleted file mode 100644 index 131e265740f37d77b7c4a3676d2a7704ca3e4a29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 McmZQz0D%Su009U9fdBvi diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab deleted file mode 100644 index 1850b55bc3186fce03d867afefe3a3a53bf94b4e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmeH@%L#xm5C#2v5X3HQ#wx@@EJLsa8xZWlHtfPUizavy3wRHb*=&9=bGOwIDQ)s; z?qUTa!x8Je&&0GDAq7?StbBhAyWhpm`*vr73G87CTbRM)bS{Srw0{N&6d8~K8IS=P UkO3Kx0U3}18IS=Pkb$2DE+S_kcmMzZ diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream deleted file mode 100644 index 2459ed687d441aba38ffb9935e376d2ba65878a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 tcmeIu0TBQ|1OPDn(?7BvZi}$UdcP+yV8DO@0|pEjFkrxd0Rsl^4lG}^02TlM diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len deleted file mode 100644 index 379d85ced69049230006887a8ba1241e30c6e7df..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 LcmZQz00VXa01p5N diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len deleted file mode 100644 index 817b326d9eb94f6a38f5e047201a69ab944ef476..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 LcmZQz0D~O>0Kfpb diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at deleted file mode 100644 index c4d33bceaf3443f1a598733983539d21825dcf4f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 478 zcmb8qO%8%E5QgC%g#~N7(1n<2`~ibTBUYnJGl7ZLLQAH_#M=u-joTjJ`Q91MQiK92 z5SSY(f~BD#L$cC3)Gh^k+d_SUvcZEh1Xmoeewc~fI$0bq@k)f;QqC)on&068yf#uh zPC&de1(tjxwdyJ7sj@cIs)!AJTAk{8wxts`_M!U*={bj7l^;K1k+=W06Bhf}vsChz U7HDguZTJ0*O?_wH7yM1U0CO9p>Hq)$ diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i deleted file mode 100644 index 0667ccd230691e805561eaf82040d187c95dd0f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32768 zcmeIuD-M7_5JbV@w`X68T)7g-5osJ}Al1oBMvSUzwbf@m_ma-Erjg!e#{d8T diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len deleted file mode 100644 index 131e265740f37d77b7c4a3676d2a7704ca3e4a29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 McmZQz0D%Su009U9fdBvi diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab deleted file mode 100644 index 6d7383f0f08dab88b6e74788c3ee4abb221369c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmeIvO-K}B9Khi>D>aMNLr5Q&g+eb25rlY%0wLIg2*o0{3t=51N+K#OBtpbPh+zbM zTS$a;h=Q`{140bSL+(K&A}BftffqZ7f_-eyQVX6scXq zP0gQ!w&fvoJ1m&um8JJAb6(s^Q(SxU_hjky()z#5d;U5%jB^XexQox2 z`dH6y?qC;Nd6Fl1n3vej$86;U)0}4$H?H)(Y-9s7Oz|k|c%Df<!w)>iNj~H|zULcORE99hM!sN{BkbV=-sL^! zd7FzIWNK9imzm=Q_Op+p?ByKKa#K|ZrK>&16 diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream deleted file mode 100644 index 99d0341fe91fcb43884b1f46a469e22d380f0f3b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmeHJO>fjN5Vb^E*lqbJq6au2AwWVx3jcwM0}@4rA|Z}uu@*O3J0$L^@au8xI3C-R z;BZ6Q-a2pQ&GUR^30Zx-V$HAjT$C+YUeX;cDk?UFEZMeJ+TN#othSQ4wHj8y)$*zmmS?y@U<-1o)E>zLbrr65wtm?Ng zHS3WUB|+_a<5Rnt^VEEBPB#p3Uv_qTRMMck=H$Gg>r&qdeRfh0Si=-`HzGw&zVMO{ z#GhDO>rKG)9e0jK--HtwtTdJHS&A*V*vS&h>!d%7`c#;95C=cO;KCePVa}PktqF-~ z2C+RE0bPa>_@?4Y-|!LC4$Y%jobNTUmvYJj6m`nYrg}D-3KqjA&GQB6^8$`GOuaoj z|NPZ_17^ewpU=D)`{1PU(W>+X&T-T0{W30J$d=Y{Mu0g8kI@8n?+Lg8lYVX_C!PGd zO}ZIX&&O54Cj)(%5l(5QyVsl#R7~ zBKRG6ibaPfocN08c)K#>_(CPG{;CAN!E2fq7YxHcgu0oS7wT#OmjFH#6dEh^3|E=kQR@klJr@J%cTOUx-v4KB$qN=#2> zVE_U)Fv-LLVuP3vJ|kEZnPlSusQ>{+AZEd;3&Sk1sZ2oi%xLCgs05ogz@ic$-+=(w z#XuV5C{`dw2@`lYAp8Ypfqei87e=_hS->o2kU5ADfSZ5_NmhdX2RjDhBnISoL1r_7 bO(C9S2CK&;A-*7wgoG8uKghmEmA&2CYv=PrdjB?6psiH0r3;4L|uEj zEH_E~nNo&A5NN@Al|MP6N{Cn#gF68Q?lzBZStsY(Lyo#|@@*@PBUfN#=Trg(s3X2x zOBOiQX)k96%fK&V^d}J@0s<3gN4#kru@Qk-pGx-J&21Fnl_xJagcK@)~xdJE5%Ppm4s4w+d z5nlG}sGT2yT8x9)_<9^aFOK&%V_ZwyCw_OlC-smbfm+NLFO{0=fJ6pA1$Aj`asThV zD=;tKjo86?-&7*_C`}?j1c-ps2xP&NUwq?Xr#WQAkrMlwUdlK1Ldyxny7f7@d!x{C zDIO8vL%@RjGE36j1U^2fulo>KgF2YzcP*G=WlYgCp)$YltEs&=~OM-DoGs? zAOemMSdIIVbBXrfdpqKbY{f$$1?zXrpGoM!!O%OOTbpI39b#m2LiF$EAnBIGH<;B&m3G+JdX{w&9J=sZ{fD-fN>&MXNTq(4` zKKty!BChtV*hOPMVqZfdt+T8Qh)8v4aD5DK(Dm6buS33@PHYGiY1)!aD-Gk_q1P%U z3xEA!G}g$kLi1G2v`ty)tHjmgA<*i5&>Zegrn|+rKZ>Ljhch|-e;o}v3&iw zs(&5wY;8Vs%~k%%FA*RDM1XYyTGVNu^WDm0!Hw(H|=^hU6>zm;)`P=vzR=?r!BQLqI+j>mj!VoZmySLsHB}_CIM#1mW zrd)}d>cR-*nn40O%-t3=HY_6{)a#To)crc z`@Z-7PZv?0Qeu9s8+Cy9et@W;P%?H2XnX#@&XE|={f@jHb>K=@eS+P@>4aMoFk*b0 Ps_4D9TMr_MXP&@cIw0dS diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab_i.len b/wikigame/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab_i.len deleted file mode 100644 index 131e265740f37d77b7c4a3676d2a7704ca3e4a29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 McmZQz0D%Su009U9fdBvi diff --git a/wikigame/build/kotlin/compileKotlin/cacheable/last-build.bin b/wikigame/build/kotlin/compileKotlin/cacheable/last-build.bin deleted file mode 100644 index 0791d768e94d2f02f3af305cc50525f4085dcb08..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18 YcmZ4UmVvdLhk=2yE9`X6Q3fCY05;MD{{R30 diff --git a/wikigame/build/kotlin/compileKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin b/wikigame/build/kotlin/compileKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin deleted file mode 100644 index 1a06c20dd221968fd7ee2e1b2d0d6910f5f30680..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1890 zcmb_cyKWOv5IqoQ{fBoeKB@66npGiT1d09K&C>o~#$Q^Xiyj8k-wB0|Dl=xk^F zopLv!7ieLB$=hRGgwBWk%E$QT7v;Rn?+RY?-~R2f@5U1Qfn@;q>yMdSw%GBGtG_K1GXQ@WQ*at{AR zuWM9RNR%luh5GyUw}(H{PY=Gc5bpA;d782~*>Xi?wmOju)o`BOl+h$s;XmSue!;U! zhJ?c6TIcj-Ss6u10F6Iwt*GrkbECIXLZJD^&P?OZeG|5%R VNmi{j-}$d><_nx}kGdQo`2*fPNY(%V diff --git a/wikigame/build/kotlin/compileKotlin/local-state/build-history.bin b/wikigame/build/kotlin/compileKotlin/local-state/build-history.bin deleted file mode 100644 index d8328c4e8542f8592206d22df66e4087a40d44d7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31 ccmZ4UmVvcgk^ur385kJ5!cONLh4L8~0AfJ}4FCWD diff --git a/wikigame/build/tmp/compileJava/previous-compilation-data.bin b/wikigame/build/tmp/compileJava/previous-compilation-data.bin deleted file mode 100644 index 73117b8441d3d46d8898f38ed33d54f6c747cc26..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3266 zcmb7H3se(V8ot*Oc_?^=QqZovMA-E)Mz99O*u{hj#6Zmiu%g5v8N!6gOvp?Ku)ZJ( zZ($|9$tKfj|w35yUH?(!w*G=mnfs$|?cnBY~4*IONyh>e}mQ9TPRN`ZDRhvIT%O z;D0_pTukvMeF$H|4^$QMBFk{2fYVfLmW&3~qLtB$`4-fF?!t|-u9OZ-(}?gJB~Hp; z6OiUJ1~`h%2vpK~-fBR9sPj2da@Y4m{Y4pnKt@Y#hnwr-zqojQRS7Y1A=0S9bB3m?h8O;Pk+ueaU@rmw;k5t>LM zitwEXYVcaoR*qsN(V&*L(3D8!vGgQR!*e2DH`g{y52w7Roh)y?+`g;9)}E`-2F^u+t2R?*!nV)Fhx=l6<)3}4OioUI zi&#MTrC=p+HnSi}1x`GsfhrEmhZfK&dvx2GGc)SH1K8%M&vOpBbK7QerF!e zJ9N{&Ta$aICp}Ii(*v|v^ky18OBhl9+LEK{xVV4b@FjKEGL>2Lv(-V1fzu|4?|=$= z38>}uHZv}eHXudt+_2-$r(uqWeL>`ApVFL#OQYqIWxz!j(=0l6HssERf$uM;)qV7& zOByE6)dWSOO_HPAMjweaychU4{R7m0T&G&Dp@=-fZ=ytxNe?aV9Q47h84nJg9vKMQ z{vtnHHa^~vM3ec+QX{A@v0x<+rl;5fP$?Q%ToZ0PgSJL`Wqkbg#oHHUd4FH8@%@)+ zVWCpWf;!q_rS(IyUxwmSHr?wTG4l({ltYs)ouB7rCj2;1B@9JDj=zS_Jvm`@NcXZp z^HmNUmvZ_7E6*`ycs05! z>37cT9GI!HnG=d^tGk4SA{k%<^)Ic5T~dtoWzI8DXwBNLN5bU`9f!AaUNh4M`s^7c z+ESv7_zkfFIC-maC8#ygVxAQnN>~Nzf7}8D$!g%F1#u0;I$=vuv!h#oa{k@KgQ0Pk zy4M_TDTnD5@a+Hx1XYy2kTTL*bhV_>bfEoV)Ioda&6C~X4kuK&pt=$gRgkELL=7ZX z)WR3GW?9Bm2Z4*FIO8fwJ^n`-8GQr9g5v~{!m92axB7Y6k}y}w%FeqneMdicL&aK{ zo$)TthlR%5L=7Sv_8;%>tozO$;E=4p#S`nGVm*x3NhYDZYubm7(4%+HO1@w4jk_$n z5t7mkIJnJ%nYXY&T5a1GA;S#o;Nzh|ZjNb;r)+Z%)(yz8Yu#^oVwfH|P|2n^jLoSYI9q5kE>M zBDR=fZFFoz0VPD}3vg>`gTKd!u@Jx}2tvUjGjFi5^fZRc=Og(1h}i$0GQ_Ymh8R3y zhNYbFbCH7w&@f~;PQ4C-7(6He;W6`gj}bBm0^;R{aD`6rSGK@%i2Lt`AQ6J`@iKXm zDl^w0l*2|$stIm{-u{G|)bT}b*o+_C4S^gJHGm|K(<(475hx*$ez(-7JW_WZPHh!=bBux|4n zrz-LoA$W|idyFWD9z&d-L$EA8^**+er;tX^Ax#j1kRi9c^vX{-WuxbDu`oSl--4-N z4Y%SUa;#jz3$olM7;n&-63elLa~h%A+rJqbm&6v1Ny3IFRGFCB4*a}itiqIoo!Ex6 z{$B|bgS+}L9e4a3h-?^S_aIRve$jyVMFZ}I#79v5F`V8Br@!JQ8M$xpc%X`@!8!cJ GpZ@?4aI1X) diff --git a/wikigame/build/tmp/jar/MANIFEST.MF b/wikigame/build/tmp/jar/MANIFEST.MF deleted file mode 100644 index 58630c0..0000000 --- a/wikigame/build/tmp/jar/MANIFEST.MF +++ /dev/null @@ -1,2 +0,0 @@ -Manifest-Version: 1.0 - diff --git a/wikigame/completable-future/build/classes/kotlin/main/META-INF/completable-future.kotlin_module b/wikigame/completable-future/build/classes/kotlin/main/META-INF/completable-future.kotlin_module deleted file mode 100644 index 1e9f2ca4d180a083a06174d407c30581ce729120..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24 YcmZQzU|?ooU|eSnEDq8~2%LkOPe|RU{AdV_hQMeD jjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kgRc_9D*#r_JH diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream deleted file mode 100644 index d5abc42a57ab711d3c4ec3c4836d9376b2099e10..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmeIuK@LDL5Cu?&>6Y2sBEp7<#8O5xl4^@o>-^3k`R@p?RO2-CO*OA|H!0GWznw(h xoaB3oDF{75lV@|%!7tNdtZCUxVPgguzyJm?fB_6(00S7n00uCC0Sx?O-~(=K6ukfd diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len deleted file mode 100644 index 130ab288134144812e637e1779d150d9a83c3d73..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 LcmZQz00V0P07C#g diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len deleted file mode 100644 index 2a17e6e5bd9e7704741c2a3ae485eb2d2e302b87..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 LcmZQz0D}$y0FVHQ diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at deleted file mode 100644 index 40858a77024e3490543fcd88da7b4d218d3426cc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 314 zcmb`CI}UvC=wRTmkl3!rB6PygO}R!q*|-QB~hA*{SJLUPo-uY9(~g6UL)=-XQC} zB*6v(YtgbeSnEDq8~2%LkOPe|RU{AdV_hQMeD jjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kgRc_9D*#r_JH diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream deleted file mode 100644 index bfcae2c8e2f3c522c3d0bbb9af7b5723c44b0000..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmeIuF%1A93;;0BIYR>X4vuA+{}&&mmC!iVwR7&mfB^#r3>YwAz<>b*1`HVZb>IPI C1p^lV diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len deleted file mode 100644 index 9a6f654a2b1fe7f7cba4b266715a7a764968b486..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 LcmZQz00T|{01*HR diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len deleted file mode 100644 index 2a17e6e5bd9e7704741c2a3ae485eb2d2e302b87..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 LcmZQz0D}$y0FVHQ diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at deleted file mode 100644 index 53b2d29f95c6af74266544729b594570fda94d3b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52 zcmdOA@JLNeNi9+cN=?o$N>OmjFH#6dEh^3|E=kQR@klJr@J%cTOUx-v4KB$qN=#2> HWMBXQ-PsZa diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i deleted file mode 100644 index 0ea07a00c729455d91a6698c991502c763529461..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32768 zcmeIuK@9*P5CpL$SmwtEVW>d~$heS>f=ScTBLV~n5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAW%$Ty`MA3F1BTd009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk c1PBlyK!5-N0t5&UAV7cs0RjXF5cpW&0s|le5&!@I diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i.len b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i.len deleted file mode 100644 index 131e265740f37d77b7c4a3676d2a7704ca3e4a29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 McmZQz0D%Su009U9fdBvi diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab deleted file mode 100644 index bdf584a84b58bf0b45e9b3a4c946653433feaad2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmbR3vzw0r2pB;G3eSnEDq8~2%LkOPe|RU{AdV_hQMeD jjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kgRc_9D*#r_JH diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream deleted file mode 100644 index bfcae2c8e2f3c522c3d0bbb9af7b5723c44b0000..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmeIuF%1A93;;0BIYR>X4vuA+{}&&mmC!iVwR7&mfB^#r3>YwAz<>b*1`HVZb>IPI C1p^lV diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len deleted file mode 100644 index 9a6f654a2b1fe7f7cba4b266715a7a764968b486..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 LcmZQz00T|{01*HR diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len deleted file mode 100644 index 2a17e6e5bd9e7704741c2a3ae485eb2d2e302b87..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 LcmZQz0D}$y0FVHQ diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at deleted file mode 100644 index 70664de958749a7f1e42d441d66c9618b1cf1ff4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 110 zcmV~$%MOAt5Cu>^r3A~DbK&LAq2Q`Xctlfe>fUze{r2|Uoor1m#U()b6|j02Edt8oD6*gF%Ri=vpZt*{ H)|37LQ?Dlb diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i deleted file mode 100644 index 0ea07a00c729455d91a6698c991502c763529461..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32768 zcmeIuK@9*P5CpL$SmwtEVW>d~$heS>f=ScTBLV~n5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAW%$Ty`MA3F1BTd009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk c1PBlyK!5-N0t5&UAV7cs0RjXF5cpW&0s|le5&!@I diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len deleted file mode 100644 index 131e265740f37d77b7c4a3676d2a7704ca3e4a29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 McmZQz0D%Su009U9fdBvi diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab deleted file mode 100644 index 49dfd8cf0c35cc8f69cc3bc6c715a7488a002e54..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmbR3vzw0r2$(jE2By2#kinXb6mkz-S1JhQMeDjE2By2#kinXb6mk0O=tB01EdGI{*Lx diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream deleted file mode 100644 index d86315ba75e7d44683eec4fb432687fd5976b9be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmd-G&&Mc1k(>yEqH(!3zuXtyCkNE zWSh%XIUj L-*d!r)W7l%{;NCk diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i deleted file mode 100644 index 41a6da792bceecb494ff910b2358608b678ce367..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32768 zcmeIuK@Gql5Jb@pSgJH`O$faq3N_VG0YwJMzESY!MTr_lfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C74igx==e^rHEK3dn0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyKp?Ha+|RH6 qJ!t_PCqRGz0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5;&6aqg2W(C3k diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len deleted file mode 100644 index 131e265740f37d77b7c4a3676d2a7704ca3e4a29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 McmZQz0D%Su009U9fdBvi diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab deleted file mode 100644 index 51530698cf4e5fbd44339183475807a13635be84..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmbR3vzw0r2$(R diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream deleted file mode 100644 index b168a7b3775c732d604349beec38ecd24cb77cf1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmeIuu?+wa5I|9-$|%+_f>I4qH5FIx$U6&#uryw3;52X}JgIBN82B{#n*z;({8oDuIGXeXLdhI{#Bo_zX z7Yy$`Lq?dBOSW{VT%NpCF4>T4iiYXT88)Xi);qKsR8i~gXy?bN7P85M#7;Y2Vt zN_(Q(fIh}BSLtB&5UPoe{79vK>dk|2I1wir^s2QAZ^Y^B{x=v&t8~467T?7ymb8%U z*A{=eIT$yLjyJOZQLrVrrE`8wy2Q(pYCg$lbg0VO664;|)3N2&(X6kCg+0MQ(2ezX I2amn}13YdtVgLXD diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i deleted file mode 100644 index 9196d2b59d0d608f133ec403a79a91f1b8d5f6b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32768 zcmeIuu?>JA6h+Y=U760t(xKRau!2j_P{<61;uq%)aPxBFh%<};0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&o6S&u(_bN5nEq4eIAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U vAV7cs0RjXz3p}egdmEdxas&tvAV7cs0RjXF5FkK+009C72oNAZ;FrJ$x>^S= diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len deleted file mode 100644 index 131e265740f37d77b7c4a3676d2a7704ca3e4a29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 McmZQz0D%Su009U9fdBvi diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab deleted file mode 100644 index bdf584a84b58bf0b45e9b3a4c946653433feaad2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmbR3vzw0r2pB;G3eSnEDq8~2%LkOPe|RU{AdV_hQMeD jjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kgRc_9D*#r_JH diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream deleted file mode 100644 index d5abc42a57ab711d3c4ec3c4836d9376b2099e10..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmeIuK@LDL5Cu?&>6Y2sBEp7<#8O5xl4^@o>-^3k`R@p?RO2-CO*OA|H!0GWznw(h xoaB3oDF{75lV@|%!7tNdtZCUxVPgguzyJm?fB_6(00S7n00uCC0Sx?O-~(=K6ukfd diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len deleted file mode 100644 index 130ab288134144812e637e1779d150d9a83c3d73..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 LcmZQz00V0P07C#g diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len deleted file mode 100644 index 2a17e6e5bd9e7704741c2a3ae485eb2d2e302b87..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 LcmZQz0D}$y0FVHQ diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at deleted file mode 100644 index f2a68686e4306333f077165fd0021c38b125d8b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 97 zcmdOA@JLNeNi9+cN=?o$N>OmjFH#6dEh^3|E=kQR@klJr@J%cTOUx-v4KB$qN=#4H tW8etS%+7RA%uN-AF;rYq(-KQ_N<4E5a*Fx%vhz!FGV|hd^HWN5QUQxnBMSfk diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i deleted file mode 100644 index 9d2eca8c0c3fa9f616c99d992a152577d3028e10..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32768 zcmeIuQ4s(T6h*;nh#{6h63RpgKX3LlIGdIp5geSnEDq8~2%LkOPe|RU{AdV_hQMeD jjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kgRc_9D*#r_JH diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream deleted file mode 100644 index d5abc42a57ab711d3c4ec3c4836d9376b2099e10..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmeIuK@LDL5Cu?&>6Y2sBEp7<#8O5xl4^@o>-^3k`R@p?RO2-CO*OA|H!0GWznw(h xoaB3oDF{75lV@|%!7tNdtZCUxVPgguzyJm?fB_6(00S7n00uCC0Sx?O-~(=K6ukfd diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len deleted file mode 100644 index 130ab288134144812e637e1779d150d9a83c3d73..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 LcmZQz00V0P07C#g diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len deleted file mode 100644 index 2a17e6e5bd9e7704741c2a3ae485eb2d2e302b87..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 LcmZQz0D}$y0FVHQ diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at deleted file mode 100644 index 5875372349163668e6e0a816c8855cd692143458..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55 zcmdOA@JLNeNi9+cN=?o$N>OmjFH#6dEh^3|E=kQR@klJr@J%cTOUx-v4KB$qN=#2> HVE_RD6bTXt diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i deleted file mode 100644 index 9d2eca8c0c3fa9f616c99d992a152577d3028e10..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32768 zcmeIuQ4s(T6h*;nh#{6h63RpgKX3LlIGdIp5g^r3A~DbK&LAq2Q`Xctlfe>fUze{r2|Uoor1m#U()b6|j02Edt8oD6*gF%Ri=vpZt*{ H)|37LQ?Dlb diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len deleted file mode 100644 index 1b1cb4d44c57c2d7a5122870fa6ac3e62ff7e94e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 KcmZQzfB*mh2mk>9 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab deleted file mode 100644 index 3ea04f76c98f3a4cdc56e84cf6b74d5030138d74..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmbR3vzw0r2)IB53hQMeD ljE2By2#kinXb6mkz-S1JhQMeDjE2By2#kinXb7N%007&8E=B+V diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream deleted file mode 100644 index 56133765245d534d6cd58fbaaa715b1329cd7f96..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmeIuK?;B%5CzbILRxo_t`R}I7Og`h25p4&{*;R00b2f9>33#?N7OA6>8*a{kPm8$ zH_Mr_VQ0(pahY_muK_7c*6C9ME5Az diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len deleted file mode 100644 index b8b8413172e1315b6cc60273b2d4eb80b6e8efaa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 LcmZQz0E6iO0G|Mu diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.len b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.len deleted file mode 100644 index fd5292d4bdcdb76028e1eb3dd4835aa24aab9241..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 LcmZQz0D}tv0N4Q0 diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at deleted file mode 100644 index 7c9e2992f2ba722ca444d6fdc69223ba5ab10242..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 109 zcmdOA@JLNeNi9+cN=?o$N>OmjFH#6dEh^3|E=kQR@klJr@J%cTOUx-v4KB$qN=#2> JVE_U0NC4&@5-b1! diff --git a/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab_i b/wikigame/completable-future/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab_i deleted file mode 100644 index 6e45739fc5241e90bd4208a995800f57a83b3279..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32768 zcmeI$Ax;B96b9f)L4hD(aYzn8!Zk=R2*MqDfhIM`I*>>l7?KJ|R$^(Y(A8a%HI=*@ zY_hw_PCDP%o%iPdKe_2B9VBNof%ka%=VSghS^y6d*kgfNbUXdM*yDy}R$D~v`ue0P zv%S^?2oNAZfB*pkeFeT_!DW4S)pw710t5&UAV7dXn?My8{%&^u|F=Q;PJjRb0t5&U zC`{lb`Zl*upM}*{mjD3*1O^s(jD3^o!{NYdts_8y009C72oNAZfB*pk1PBo5D6ovV zv*!4#!P=E4eEi|T>bj}`wYHM zejw2i-?nbxt>}~Xb*qL`tVcJqTZuI%Vl7&Hq>P>c*an6|Nn5dOs%O2xwZcm~p!_V~ z8?N2QPWc!%Q!Irr^ljsNM{rNssMMQN+u%&CNUuzuvsvLP=I9D{1ty{X-h&&Wt?Knn z8lutO!#r5%9tJy2m@ge{tet~3PwfqDx7cx1I$P=sxM#X-eUkQ^JKl$GK3wL#GZC}9 z)kFBr=^Un9A8dE$HcU`CV^;SC0R10Af-F1^@s6 diff --git a/wikigame/completable-future/build/tmp/compileJava/previous-compilation-data.bin b/wikigame/completable-future/build/tmp/compileJava/previous-compilation-data.bin deleted file mode 100644 index bf65c07a28fdc4debc909bda1d6cb5a412aef890..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23846 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 O6_c(m&YRE;{{8@Hv)};$ diff --git a/wikigame/completable-future/src/main/java/Main.java b/wikigame/completable-future/src/main/java/MainFuture.java similarity index 94% rename from wikigame/completable-future/src/main/java/Main.java rename to wikigame/completable-future/src/main/java/MainFuture.java index b765121..82d9576 100644 --- a/wikigame/completable-future/src/main/java/Main.java +++ b/wikigame/completable-future/src/main/java/MainFuture.java @@ -1,4 +1,4 @@ -public class Main { +public class MainFuture { public static void main(String[] args) { long startTime = System.currentTimeMillis(); WikiGame wikiGame = new WikiGameFutureImpl(); diff --git a/wikigame/coroutines/src/main/java/coroutines/Main.kt b/wikigame/coroutines/src/main/java/coroutines/Main.kt index 5377182..ae23806 100644 --- a/wikigame/coroutines/src/main/java/coroutines/Main.kt +++ b/wikigame/coroutines/src/main/java/coroutines/Main.kt @@ -1,10 +1,10 @@ package coroutines import coroutines.repository.WikiGame -import coroutines.repository.WikiGameDumbImpl +import coroutines.repository.WikiGameCoroImpl fun main(args: Array) { - val wikiGame: WikiGame = WikiGameDumbImpl() + val wikiGame: WikiGame = WikiGameCoroImpl() val start = System.nanoTime() val path = wikiGame.play("Бакуган", "Библия", maxDepth = 6) diff --git a/wikigame/coroutines/src/main/java/coroutines/repository/WikiGameDumbImpl.kt b/wikigame/coroutines/src/main/java/coroutines/repository/WikiGameCoroImpl.kt similarity index 98% rename from wikigame/coroutines/src/main/java/coroutines/repository/WikiGameDumbImpl.kt rename to wikigame/coroutines/src/main/java/coroutines/repository/WikiGameCoroImpl.kt index b63a7dd..29d0763 100644 --- a/wikigame/coroutines/src/main/java/coroutines/repository/WikiGameDumbImpl.kt +++ b/wikigame/coroutines/src/main/java/coroutines/repository/WikiGameCoroImpl.kt @@ -9,7 +9,7 @@ import java.lang.RuntimeException import java.util.Optional import java.util.concurrent.ConcurrentHashMap -class WikiGameDumbImpl : WikiGame { +class WikiGameCoroImpl : WikiGame { companion object { private const val REQUEST_SENT = 1 private const val RESPONSE_RECEIVED = 2 diff --git a/wikigame/coroutines/src/main/java/coroutines/wiki/WikiRemoteDataSourceImpl.kt b/wikigame/coroutines/src/main/java/coroutines/wiki/WikiRemoteDataSourceImpl.kt index 1710448..d083383 100644 --- a/wikigame/coroutines/src/main/java/coroutines/wiki/WikiRemoteDataSourceImpl.kt +++ b/wikigame/coroutines/src/main/java/coroutines/wiki/WikiRemoteDataSourceImpl.kt @@ -24,7 +24,7 @@ class WikiRemoteDataSourceImpl : WikiRemoteDataSource { private val rateLimiterConfig = RateLimiterConfig .custom() .limitForPeriod(1) - .limitRefreshPeriod(Duration.ofMillis(3)) + .limitRefreshPeriod(Duration.ofMillis(40)) .timeoutDuration(Duration.ofDays(10000)) .build() diff --git a/wikigame/executor/build/classes/kotlin/main/META-INF/executor.kotlin_module b/wikigame/executor/build/classes/kotlin/main/META-INF/executor.kotlin_module deleted file mode 100644 index 1e9f2ca4d180a083a06174d407c30581ce729120..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24 YcmZQzU|?ooU|eSnEDq8~2%LkOPe|RU{AdV_hQMeD jjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kgRc_9D*#r_JH diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream deleted file mode 100644 index e1ab609e4c43355cd9ebe548e8fb2b45bcbf13a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmeIu%L#xm5I{kT$=S6B714_l1dp2(3^2d|0}L?000Rs#zyJe(8~6Z(*$~nI diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len deleted file mode 100644 index 1c209ae2a7dc1bbbb98f55f92e253f91b6f5ef9d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 LcmZQz00Tn+0673M diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len deleted file mode 100644 index 2a17e6e5bd9e7704741c2a3ae485eb2d2e302b87..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 LcmZQz0D}$y0FVHQ diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at deleted file mode 100644 index a5b615a3351f17d1d7f41d761376bdc800d97dd0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 274 zcmbV`!3u&v6h(!8#D&|OPl!lOBTGzbDKF<$gKr#}Hv@fb-;yM>ug%>Y?%{|aN04a4 z8arcUm>C;ZXj!qt!R5e@62>!-$CEP_?)X{+tEj4vyL8jENl`}vpV;{cimO*7MMuDl zEPCTe4MM{-7uBmRXpBE_|Mx#i@CKe-p-19bR{bn1(`LOa4%s(6o>Nk7i=i diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i deleted file mode 100644 index 264e3d2c81aba569068b339f59e7c27605f3f8ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32768 zcmeIu0Sy2k5CgFhoL~Zbct8`rKn9<53T{nHj}ah1fB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C73Ja{)e)gD!FGwdqfB*pk1PBly cK!5-N0t5&UAV7cs0RjXF5FkK+0D%t#E>b}PHUIzs diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i.len deleted file mode 100644 index 131e265740f37d77b7c4a3676d2a7704ca3e4a29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 McmZQz0D%Su009U9fdBvi diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab deleted file mode 100644 index bdf584a84b58bf0b45e9b3a4c946653433feaad2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmbR3vzw0r2pB;G3eSnEDq8~2%LkOPe|RU{AdV_hQMeD jjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kgRc_9D*#r_JH diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream deleted file mode 100644 index bfcae2c8e2f3c522c3d0bbb9af7b5723c44b0000..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmeIuF%1A93;;0BIYR>X4vuA+{}&&mmC!iVwR7&mfB^#r3>YwAz<>b*1`HVZb>IPI C1p^lV diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len deleted file mode 100644 index 9a6f654a2b1fe7f7cba4b266715a7a764968b486..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 LcmZQz00T|{01*HR diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len deleted file mode 100644 index 2a17e6e5bd9e7704741c2a3ae485eb2d2e302b87..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 LcmZQz0D}$y0FVHQ diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at deleted file mode 100644 index 53b2d29f95c6af74266544729b594570fda94d3b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52 zcmdOA@JLNeNi9+cN=?o$N>OmjFH#6dEh^3|E=kQR@klJr@J%cTOUx-v4KB$qN=#2> HWMBXQ-PsZa diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i deleted file mode 100644 index 0ea07a00c729455d91a6698c991502c763529461..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32768 zcmeIuK@9*P5CpL$SmwtEVW>d~$heS>f=ScTBLV~n5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAW%$Ty`MA3F1BTd009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk c1PBlyK!5-N0t5&UAV7cs0RjXF5cpW&0s|le5&!@I diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i.len deleted file mode 100644 index 131e265740f37d77b7c4a3676d2a7704ca3e4a29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 McmZQz0D%Su009U9fdBvi diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab deleted file mode 100644 index bdf584a84b58bf0b45e9b3a4c946653433feaad2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmbR3vzw0r2pB;G3eSnEDq8~2%LkOPe|RU{AdV_hQMeD jjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kgRc_9D*#r_JH diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream deleted file mode 100644 index bfcae2c8e2f3c522c3d0bbb9af7b5723c44b0000..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmeIuF%1A93;;0BIYR>X4vuA+{}&&mmC!iVwR7&mfB^#r3>YwAz<>b*1`HVZb>IPI C1p^lV diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len deleted file mode 100644 index 9a6f654a2b1fe7f7cba4b266715a7a764968b486..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 LcmZQz00T|{01*HR diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len deleted file mode 100644 index 2a17e6e5bd9e7704741c2a3ae485eb2d2e302b87..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 LcmZQz0D}$y0FVHQ diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at deleted file mode 100644 index 7ffc2f7eae72d74f37a84f9223162e50017d1899..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 100 zcmWN`K@Ng25Cu?<(gkZr&wwJD7)dpm}}{?*wd A1^@s6 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i deleted file mode 100644 index 0ea07a00c729455d91a6698c991502c763529461..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32768 zcmeIuK@9*P5CpL$SmwtEVW>d~$heS>f=ScTBLV~n5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAW%$Ty`MA3F1BTd009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk c1PBlyK!5-N0t5&UAV7cs0RjXF5cpW&0s|le5&!@I diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len deleted file mode 100644 index 131e265740f37d77b7c4a3676d2a7704ca3e4a29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 McmZQz0D%Su009U9fdBvi diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab deleted file mode 100644 index 4bd7a9b70da379f8d9d0bff8d516fb08256ab731..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmbR3vzw0r2$(jE2By2#kinXb6mkz-S1JhQMeDjE2By2#kinXb6mk0O=tB0HuEpMF0Q* diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream deleted file mode 100644 index d86315ba75e7d44683eec4fb432687fd5976b9be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmd-G&&OmjFH#6dEh^3|E=kQR@klJr@J%cTOUx-v4KB$qN=#2R zWH3+(2=e!Gbq1QRDCF+M~W@ox5=BDapmyn?a E0B4Fc2mk;8 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i deleted file mode 100644 index 41a6da792bceecb494ff910b2358608b678ce367..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32768 zcmeIuK@Gql5Jb@pSgJH`O$faq3N_VG0YwJMzESY!MTr_lfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C74igx==e^rHEK3dn0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyKp?Ha+|RH6 qJ!t_PCqRGz0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5;&6aqg2W(C3k diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len deleted file mode 100644 index 131e265740f37d77b7c4a3676d2a7704ca3e4a29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 McmZQz0D%Su009U9fdBvi diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab deleted file mode 100644 index fe53097dddf9fb8bf8ea494ffa3fdba96f831055..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmbR3vzw0r2$(Ia!dMKqAgV$b*25BLrr9CfZ)nGK?8iwms6v#BVaY zO-0u}4yLUoV>8MBE^Wmy;d61H@I>7^H})W#$Q^Gl^6P9k45d4Qk)V$lY7Vah-vGCY BFl_(; diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i deleted file mode 100644 index 9196d2b59d0d608f133ec403a79a91f1b8d5f6b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32768 zcmeIuu?>JA6h+Y=U760t(xKRau!2j_P{<61;uq%)aPxBFh%<};0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&o6S&u(_bN5nEq4eIAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U vAV7cs0RjXz3p}egdmEdxas&tvAV7cs0RjXF5FkK+009C72oNAZ;FrJ$x>^S= diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len deleted file mode 100644 index 131e265740f37d77b7c4a3676d2a7704ca3e4a29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 McmZQz0D%Su009U9fdBvi diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab deleted file mode 100644 index bdf584a84b58bf0b45e9b3a4c946653433feaad2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmbR3vzw0r2pB;G3eSnEDq8~2%LkOPe|RU{AdV_hQMeD jjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kgRc_9D*#r_JH diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream deleted file mode 100644 index e1ab609e4c43355cd9ebe548e8fb2b45bcbf13a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmeIu%L#xm5I{kT$=S6B714_l1dp2(3^2d|0}L?000Rs#zyJe(8~6Z(*$~nI diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len deleted file mode 100644 index 1c209ae2a7dc1bbbb98f55f92e253f91b6f5ef9d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 LcmZQz00Tn+0673M diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len deleted file mode 100644 index 2a17e6e5bd9e7704741c2a3ae485eb2d2e302b87..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 LcmZQz0D}$y0FVHQ diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at deleted file mode 100644 index f2a68686e4306333f077165fd0021c38b125d8b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 97 zcmdOA@JLNeNi9+cN=?o$N>OmjFH#6dEh^3|E=kQR@klJr@J%cTOUx-v4KB$qN=#4H tW8etS%+7RA%uN-AF;rYq(-KQ_N<4E5a*Fx%vhz!FGV|hd^HWN5QUQxnBMSfk diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i deleted file mode 100644 index 264e3d2c81aba569068b339f59e7c27605f3f8ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32768 zcmeIu0Sy2k5CgFhoL~Zbct8`rKn9<53T{nHj}ah1fB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C73Ja{)e)gD!FGwdqfB*pk1PBly cK!5-N0t5&UAV7cs0RjXF5FkK+0D%t#E>b}PHUIzs diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len deleted file mode 100644 index 131e265740f37d77b7c4a3676d2a7704ca3e4a29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 McmZQz0D%Su009U9fdBvi diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/counters.tab b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/counters.tab deleted file mode 100644 index 166c057..0000000 --- a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/counters.tab +++ /dev/null @@ -1,2 +0,0 @@ -1 -0 \ No newline at end of file diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab deleted file mode 100644 index bdf584a84b58bf0b45e9b3a4c946653433feaad2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmbR3vzw0r2pB;G3eSnEDq8~2%LkOPe|RU{AdV_hQMeD jjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kgRc_9D*#r_JH diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream deleted file mode 100644 index e1ab609e4c43355cd9ebe548e8fb2b45bcbf13a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmeIu%L#xm5I{kT$=S6B714_l1dp2(3^2d|0}L?000Rs#zyJe(8~6Z(*$~nI diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len deleted file mode 100644 index 1c209ae2a7dc1bbbb98f55f92e253f91b6f5ef9d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 LcmZQz00Tn+0673M diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len deleted file mode 100644 index 2a17e6e5bd9e7704741c2a3ae485eb2d2e302b87..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 LcmZQz0D}$y0FVHQ diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at deleted file mode 100644 index 5875372349163668e6e0a816c8855cd692143458..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55 zcmdOA@JLNeNi9+cN=?o$N>OmjFH#6dEh^3|E=kQR@klJr@J%cTOUx-v4KB$qN=#2> HVE_RD6bTXt diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i deleted file mode 100644 index 264e3d2c81aba569068b339f59e7c27605f3f8ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32768 zcmeIu0Sy2k5CgFhoL~Zbct8`rKn9<53T{nHj}ah1fB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C73Ja{)e)gD!FGwdqfB*pk1PBly cK!5-N0t5&UAV7cs0RjXF5FkK+0D%t#E>b}PHUIzs diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i.len deleted file mode 100644 index 131e265740f37d77b7c4a3676d2a7704ca3e4a29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 McmZQz0D%Su009U9fdBvi diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab deleted file mode 100644 index 8aad32b3b84c79ee82814f17430d858dce49687b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmbR3vzw0r2pB;G3m}}{?*wd A1^@s6 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len deleted file mode 100644 index 1b1cb4d44c57c2d7a5122870fa6ac3e62ff7e94e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 KcmZQzfB*mh2mk>9 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab deleted file mode 100644 index 3ea04f76c98f3a4cdc56e84cf6b74d5030138d74..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmbR3vzw0r2)IB53hQMeD ljE2By2#kinXb6mkz-S1JhQMeDjE2By2#kinXb7N%007&8E=B+V diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream deleted file mode 100644 index 56133765245d534d6cd58fbaaa715b1329cd7f96..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmeIuK?;B%5CzbILRxo_t`R}I7Og`h25p4&{*;R00b2f9>33#?N7OA6>8*a{kPm8$ zH_Mr_VQ0(pahY_muK_7c*6C9ME5Az diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len deleted file mode 100644 index b8b8413172e1315b6cc60273b2d4eb80b6e8efaa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 LcmZQz0E6iO0G|Mu diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.len b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.len deleted file mode 100644 index fd5292d4bdcdb76028e1eb3dd4835aa24aab9241..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 LcmZQz0D}tv0N4Q0 diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at deleted file mode 100644 index 7c9e2992f2ba722ca444d6fdc69223ba5ab10242..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 109 zcmdOA@JLNeNi9+cN=?o$N>OmjFH#6dEh^3|E=kQR@klJr@J%cTOUx-v4KB$qN=#2> JVE_U0NC4&@5-b1! diff --git a/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab_i b/wikigame/executor/build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab_i deleted file mode 100644 index 6e45739fc5241e90bd4208a995800f57a83b3279..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32768 zcmeI$Ax;B96b9f)L4hD(aYzn8!Zk=R2*MqDfhIM`I*>>l7?KJ|R$^(Y(A8a%HI=*@ zY_hw_PCDP%o%iPdKe_2B9VBNof%ka%=VSghS^y6d*kgfNbUXdM*yDy}R$D~v`ue0P zv%S^?2oNAZfB*pkeFeT_!DW4S)pw710t5&UAV7dXn?My8{%&^u|F=Q;PJjRb0t5&U zC`{lb`Zl*upM}*{mjD3*1O^s(jD3^o!{NYdts_8y009C72oNAZfB*pk1PBo5D6ovV zv*!4#pF diff --git a/wikigame/executor/build/kotlin/compileKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin b/wikigame/executor/build/kotlin/compileKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin deleted file mode 100644 index 1d79bd473dd25d9e9b2662a4ea3654f93ac01f8f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 692 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 PP>gS<4N+c%V(|9|!wdG} diff --git a/wikigame/executor/src/main/java/Main.java b/wikigame/executor/src/main/java/MainExecutor.java similarity index 94% rename from wikigame/executor/src/main/java/Main.java rename to wikigame/executor/src/main/java/MainExecutor.java index eca8b2e..1715bf6 100644 --- a/wikigame/executor/src/main/java/Main.java +++ b/wikigame/executor/src/main/java/MainExecutor.java @@ -1,4 +1,4 @@ -public class Main { +public class MainExecutor { public static void main(String[] args) { long startTime = System.currentTimeMillis(); WikiGame wikiGame = new WikiGameExecutorImpl(); From 0e1a572afb9946a7e634d93b2ad343c1ea7d623b Mon Sep 17 00:00:00 2001 From: Daniil Lyubaev Date: Tue, 5 Sep 2023 15:49:48 +0300 Subject: [PATCH 32/58] move out wiki remote source --- wikigame/build.gradle.kts | 6 ++ .../src/main/java/MainFuture.java | 2 + .../src/main/java/WikiGame.kt | 3 - .../src/main/java/WikiGameFutureImpl.java | 43 ++-------- .../main/java/WikiGameFutureSimpleImpl.java | 1 + .../src/main/java/WikiGameSerialImpl.java | 85 ------------------- .../src/main/java/coroutines/Main.kt | 4 +- .../java/coroutines/repository/WikiGame.kt | 5 -- .../coroutines/repository/WikiGameCoroImpl.kt | 3 +- .../{data/source => }/WikiRemoteDataSource.kt | 2 +- .../wiki/WikiRemoteDataSourceImpl.kt | 3 +- .../executor/src/main/java/MainExecutor.java | 2 + wikigame/executor/src/main/java/WikiGame.kt | 3 - .../src/main/java/WikiGameExecutorImpl.java | 78 ++--------------- .../src/main/java/WikiGameSerialImpl.java | 35 ++------ .../java/point/rar/repository/WikiGame.java | 7 ++ .../point/rar/wiki/WikiRemoteDataSource.java | 8 ++ .../rar/wiki/WikiRemoteDataSourceImpl.java | 81 ++++++++++++++++++ 18 files changed, 133 insertions(+), 238 deletions(-) delete mode 100644 wikigame/completable-future/src/main/java/WikiGame.kt delete mode 100644 wikigame/completable-future/src/main/java/WikiGameSerialImpl.java delete mode 100644 wikigame/coroutines/src/main/java/coroutines/repository/WikiGame.kt rename wikigame/coroutines/src/main/java/coroutines/wiki/{data/source => }/WikiRemoteDataSource.kt (81%) delete mode 100644 wikigame/executor/src/main/java/WikiGame.kt create mode 100644 wikigame/src/main/java/point/rar/repository/WikiGame.java create mode 100644 wikigame/src/main/java/point/rar/wiki/WikiRemoteDataSource.java create mode 100644 wikigame/src/main/java/point/rar/wiki/WikiRemoteDataSourceImpl.java diff --git a/wikigame/build.gradle.kts b/wikigame/build.gradle.kts index 655ccf8..e7f38e0 100644 --- a/wikigame/build.gradle.kts +++ b/wikigame/build.gradle.kts @@ -18,6 +18,12 @@ dependencies { val kotlinx_serialization_json_version = "1.4.1" implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinx_serialization_json_version") + + implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.14.2") + implementation("org.apache.httpcomponents:httpclient:4.5.13") + + implementation("io.github.resilience4j:resilience4j-timelimiter:2.1.0") + implementation("io.github.resilience4j:resilience4j-ratelimiter:2.1.0") } tasks.test { diff --git a/wikigame/completable-future/src/main/java/MainFuture.java b/wikigame/completable-future/src/main/java/MainFuture.java index 82d9576..846523d 100644 --- a/wikigame/completable-future/src/main/java/MainFuture.java +++ b/wikigame/completable-future/src/main/java/MainFuture.java @@ -1,3 +1,5 @@ +import point.rar.repository.WikiGame; + public class MainFuture { public static void main(String[] args) { long startTime = System.currentTimeMillis(); diff --git a/wikigame/completable-future/src/main/java/WikiGame.kt b/wikigame/completable-future/src/main/java/WikiGame.kt deleted file mode 100644 index 550f5fd..0000000 --- a/wikigame/completable-future/src/main/java/WikiGame.kt +++ /dev/null @@ -1,3 +0,0 @@ -interface WikiGame { - fun play(startPageTitle: String, endPageTitle: String, maxDepth: Int = 11): List -} \ No newline at end of file diff --git a/wikigame/completable-future/src/main/java/WikiGameFutureImpl.java b/wikigame/completable-future/src/main/java/WikiGameFutureImpl.java index 1c8b9ea..5665544 100644 --- a/wikigame/completable-future/src/main/java/WikiGameFutureImpl.java +++ b/wikigame/completable-future/src/main/java/WikiGameFutureImpl.java @@ -1,20 +1,17 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; -import org.apache.http.client.utils.URIBuilder; import org.jetbrains.annotations.NotNull; import point.rar.model.*; +import point.rar.repository.WikiGame; +import point.rar.wiki.WikiRemoteDataSource; +import point.rar.wiki.WikiRemoteDataSourceImpl; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; import java.util.*; import java.util.concurrent.*; public class WikiGameFutureImpl implements WikiGame { - private static final String URL = "https://ru.wikipedia.org/w/api.php"; + + private static final WikiRemoteDataSource wikiRemoteDataSource = new WikiRemoteDataSourceImpl(); @NotNull @Override @@ -82,34 +79,6 @@ private List getChildLinks(String title) { ObjectMapper objectMapper = new ObjectMapper(); objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - try { - URIBuilder uriBuilder = new URIBuilder(URL); - uriBuilder.addParameter("action", "query"); - uriBuilder.addParameter("prop", "links"); - uriBuilder.addParameter("pllimit", "max"); - uriBuilder.addParameter("format", "json"); - uriBuilder.addParameter("plnamespace", "titles"); - -// System.out.println("Get links for: " + title); - String responseBody = HttpClient.newBuilder() - .build() - .sendAsync(HttpRequest.newBuilder() - .uri(URI.create(uriBuilder.addParameter("titles", title).build().toString())) - .GET() - .build(), HttpResponse.BodyHandlers.ofString()).get().body(); - WikiLinksResponse response = objectMapper.readValue(responseBody, WikiLinksResponse.class); - - return parseLinks(response); - } catch (IOException | InterruptedException | URISyntaxException | ExecutionException e) { - throw new RuntimeException(e); - } - } - - @NotNull - private static List parseLinks(WikiLinksResponse response) { - return response.getQuery().getPages().entrySet().iterator().next().getValue().getLinks() - .stream() - .map(Link::getTitle) - .toList(); + return wikiRemoteDataSource.getLinksByTitle(title); } } diff --git a/wikigame/completable-future/src/main/java/WikiGameFutureSimpleImpl.java b/wikigame/completable-future/src/main/java/WikiGameFutureSimpleImpl.java index 01a2c57..a033630 100644 --- a/wikigame/completable-future/src/main/java/WikiGameFutureSimpleImpl.java +++ b/wikigame/completable-future/src/main/java/WikiGameFutureSimpleImpl.java @@ -6,6 +6,7 @@ import org.apache.http.client.utils.URIBuilder; import org.jetbrains.annotations.NotNull; import point.rar.model.*; +import point.rar.repository.WikiGame; import java.io.IOException; import java.net.URI; diff --git a/wikigame/completable-future/src/main/java/WikiGameSerialImpl.java b/wikigame/completable-future/src/main/java/WikiGameSerialImpl.java deleted file mode 100644 index 301f6b9..0000000 --- a/wikigame/completable-future/src/main/java/WikiGameSerialImpl.java +++ /dev/null @@ -1,85 +0,0 @@ -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.jetbrains.annotations.NotNull; -import point.rar.model.*; - -import java.io.IOException; -import java.net.URI; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.util.*; - -public class WikiGameSerialImpl implements WikiGame { - private static final String URL = "https://ru.wikipedia.org/w/api.php"; - - @NotNull - @Override - public List play(String startPageTitle, String endPageTitle, int maxDepth) { - var startedPage = new Page(startPageTitle, null); - Queue rawPages = new LinkedList<>(Collections.singleton(startedPage)); - Queue parsedPages = new LinkedList<>(); - Set parsedTitle = new HashSet<>(); - var parentEndPage = startedPage; - do { - System.out.println("parsedPages size = " + parsedPages.size()); - System.out.println("rawPages size = " + rawPages.size()); - System.out.println("parsedTitle size = " + parsedTitle.size()); - var curPage = rawPages.poll(); - parentEndPage = curPage; - var newLinks = parseLinks(curPage.getTitle()); - parsedPages.add(curPage); - parsedTitle.addAll(newLinks); - rawPages.addAll( - newLinks.stream() - .map(m -> new Page(m, curPage)) - .toList() - ); - } while (!parsedTitle.contains(endPageTitle)); - parsedPages.add(new Page(endPageTitle, parentEndPage)); - - return getResultPath(parsedPages, endPageTitle); - } - - private List getResultPath(Queue parsedPages, String endPageTitle) { - var path = new ArrayList(); - var curPage = parsedPages.stream() - .filter(p -> p.getTitle().equals(endPageTitle)) - .findAny() - .orElseThrow(); - while (curPage.getParentPage() != null) { - path.add(curPage.getTitle()); - curPage = curPage.getParentPage(); - } - path.add(curPage.getTitle()); - return path; - } - - - private List parseLinks(String title) { - ObjectMapper objectMapper = new ObjectMapper(); - objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - try { - System.out.println("Get links for: " + title); - String responseBody = HttpClient.newBuilder() - .build() - .send(HttpRequest.newBuilder() - .uri(URI.create(URL + "?action=query&prop=links&pllimit=max&format=json&plnamespace=0&titles=" + title.replace(" ", "%20"))) - .GET() - .build(), HttpResponse.BodyHandlers.ofString()).body(); - WikiLinksResponse response = objectMapper.readValue(responseBody, WikiLinksResponse.class); - - return parseLinks(response); - } catch (IOException | InterruptedException e) { - throw new RuntimeException(e); - } - } - - @NotNull - private static List parseLinks(WikiLinksResponse response) { - return response.getQuery().getPages().entrySet().iterator().next().getValue().getLinks() - .stream() - .map(Link::getTitle) - .toList(); - } -} diff --git a/wikigame/coroutines/src/main/java/coroutines/Main.kt b/wikigame/coroutines/src/main/java/coroutines/Main.kt index ae23806..ddc803b 100644 --- a/wikigame/coroutines/src/main/java/coroutines/Main.kt +++ b/wikigame/coroutines/src/main/java/coroutines/Main.kt @@ -1,13 +1,13 @@ package coroutines -import coroutines.repository.WikiGame import coroutines.repository.WikiGameCoroImpl +import point.rar.repository.WikiGame fun main(args: Array) { val wikiGame: WikiGame = WikiGameCoroImpl() val start = System.nanoTime() - val path = wikiGame.play("Бакуган", "Библия", maxDepth = 6) + val path = wikiGame.play("Бакуган", "Библия", 6) val timeSec = (System.nanoTime() - start) / (1_000_000_000f) println("$timeSec s.") println(path) diff --git a/wikigame/coroutines/src/main/java/coroutines/repository/WikiGame.kt b/wikigame/coroutines/src/main/java/coroutines/repository/WikiGame.kt deleted file mode 100644 index b1c3ef1..0000000 --- a/wikigame/coroutines/src/main/java/coroutines/repository/WikiGame.kt +++ /dev/null @@ -1,5 +0,0 @@ -package coroutines.repository - -interface WikiGame { - fun play(startPageTitle: String, endPageTitle: String, maxDepth: Int = 11): List -} \ No newline at end of file diff --git a/wikigame/coroutines/src/main/java/coroutines/repository/WikiGameCoroImpl.kt b/wikigame/coroutines/src/main/java/coroutines/repository/WikiGameCoroImpl.kt index 29d0763..caeee37 100644 --- a/wikigame/coroutines/src/main/java/coroutines/repository/WikiGameCoroImpl.kt +++ b/wikigame/coroutines/src/main/java/coroutines/repository/WikiGameCoroImpl.kt @@ -2,9 +2,10 @@ package coroutines.repository import kotlinx.coroutines.* import kotlinx.coroutines.channels.Channel -import coroutines.wiki.data.source.WikiRemoteDataSource +import coroutines.wiki.WikiRemoteDataSource import coroutines.wiki.WikiRemoteDataSourceImpl import point.rar.model.Page +import point.rar.repository.WikiGame import java.lang.RuntimeException import java.util.Optional import java.util.concurrent.ConcurrentHashMap diff --git a/wikigame/coroutines/src/main/java/coroutines/wiki/data/source/WikiRemoteDataSource.kt b/wikigame/coroutines/src/main/java/coroutines/wiki/WikiRemoteDataSource.kt similarity index 81% rename from wikigame/coroutines/src/main/java/coroutines/wiki/data/source/WikiRemoteDataSource.kt rename to wikigame/coroutines/src/main/java/coroutines/wiki/WikiRemoteDataSource.kt index d1419cd..67f6c91 100644 --- a/wikigame/coroutines/src/main/java/coroutines/wiki/data/source/WikiRemoteDataSource.kt +++ b/wikigame/coroutines/src/main/java/coroutines/wiki/WikiRemoteDataSource.kt @@ -1,4 +1,4 @@ -package coroutines.wiki.data.source +package coroutines.wiki interface WikiRemoteDataSource { suspend fun getLinksByTitle(title: String): List diff --git a/wikigame/coroutines/src/main/java/coroutines/wiki/WikiRemoteDataSourceImpl.kt b/wikigame/coroutines/src/main/java/coroutines/wiki/WikiRemoteDataSourceImpl.kt index d083383..acc37b2 100644 --- a/wikigame/coroutines/src/main/java/coroutines/wiki/WikiRemoteDataSourceImpl.kt +++ b/wikigame/coroutines/src/main/java/coroutines/wiki/WikiRemoteDataSourceImpl.kt @@ -11,7 +11,6 @@ import io.ktor.client.request.get import io.ktor.client.request.parameter import io.ktor.serialization.kotlinx.json.json import kotlinx.serialization.json.Json -import coroutines.wiki.data.source.WikiRemoteDataSource import point.rar.model.WikiBacklinksResponse import point.rar.model.WikiLinksResponse import java.time.Duration @@ -52,6 +51,8 @@ class WikiRemoteDataSourceImpl : WikiRemoteDataSource { } } + println("got response from $title") + val wikiLinksResponse: WikiLinksResponse = response.body() val links = wikiLinksResponse diff --git a/wikigame/executor/src/main/java/MainExecutor.java b/wikigame/executor/src/main/java/MainExecutor.java index 1715bf6..c50e307 100644 --- a/wikigame/executor/src/main/java/MainExecutor.java +++ b/wikigame/executor/src/main/java/MainExecutor.java @@ -1,3 +1,5 @@ +import point.rar.repository.WikiGame; + public class MainExecutor { public static void main(String[] args) { long startTime = System.currentTimeMillis(); diff --git a/wikigame/executor/src/main/java/WikiGame.kt b/wikigame/executor/src/main/java/WikiGame.kt deleted file mode 100644 index 550f5fd..0000000 --- a/wikigame/executor/src/main/java/WikiGame.kt +++ /dev/null @@ -1,3 +0,0 @@ -interface WikiGame { - fun play(startPageTitle: String, endPageTitle: String, maxDepth: Int = 11): List -} \ No newline at end of file diff --git a/wikigame/executor/src/main/java/WikiGameExecutorImpl.java b/wikigame/executor/src/main/java/WikiGameExecutorImpl.java index 700d137..9b38b9d 100644 --- a/wikigame/executor/src/main/java/WikiGameExecutorImpl.java +++ b/wikigame/executor/src/main/java/WikiGameExecutorImpl.java @@ -1,34 +1,19 @@ -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import io.github.resilience4j.ratelimiter.RateLimiter; -import io.github.resilience4j.ratelimiter.RateLimiterConfig; -import io.github.resilience4j.ratelimiter.RateLimiterRegistry; -import org.apache.http.client.utils.URIBuilder; import org.jetbrains.annotations.NotNull; import point.rar.model.*; +import point.rar.repository.WikiGame; +import point.rar.wiki.WikiRemoteDataSource; +import point.rar.wiki.WikiRemoteDataSourceImpl; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.time.Duration; import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicBoolean; public class WikiGameExecutorImpl implements WikiGame { - private static final String URL = "https://ru.wikipedia.org/w/api.php"; - private static final RateLimiterConfig config = RateLimiterConfig.custom() - .limitRefreshPeriod(Duration.ofMillis(50)) - .limitForPeriod(10) - .timeoutDuration(Duration.ofMillis(5)) - .build(); - private static final RateLimiterRegistry rateLimiterRegistry = RateLimiterRegistry.of(config); - private static final RateLimiter rateLimiter = rateLimiterRegistry.rateLimiter("rate"); private static AtomicBoolean isFinished = new AtomicBoolean(false); + private final WikiRemoteDataSource wikiRemoteDataSource = new WikiRemoteDataSourceImpl(); + @NotNull @Override public List play(@NotNull String startPageTitle, @NotNull String endPageTitle, int maxDepth) { @@ -57,11 +42,11 @@ public List play(@NotNull String startPageTitle, @NotNull String endPage return getResultPath(parsedPages, endPageTitle); } - public static Runnable makeSearch(Queue rawPages, Queue parsedPages, Set receivedLinks, String endPageTitle) { + public Runnable makeSearch(Queue rawPages, Queue parsedPages, Set receivedLinks, String endPageTitle) { return () -> { Page curPage = rawPages.poll(); if (curPage != null) { - List newLinks = getChildLinks(curPage.getTitle()); + List newLinks = wikiRemoteDataSource.getLinksByTitle(curPage.getTitle()); if (newLinks != null) { parsedPages.add(curPage); for (String link : newLinks) { @@ -93,53 +78,4 @@ private static List getResultPath(Queue parsedPages, String endPag Collections.reverse(path); // Reverse the order of elements in the list return path; } - - - private static List getChildLinks(String title) { - ObjectMapper objectMapper = new ObjectMapper(); - objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - - try { - System.out.println("Get links for: " + title); - System.out.println(rateLimiter.getMetrics().getAvailablePermissions()); - URIBuilder uriBuilder = getUriBuilder(); - String responseBody = makeRequest(title, uriBuilder); - WikiLinksResponse response = objectMapper.readValue(responseBody, WikiLinksResponse.class); - - return parseLinks(response); - } catch (Throwable e) { - return null; - } - } - - private static String makeRequest(String title, URIBuilder uriBuilder) throws Throwable { - return RateLimiter.decorateCheckedSupplier(rateLimiter, () -> HttpClient.newBuilder() - .build() - .sendAsync(HttpRequest.newBuilder() - .uri(URI.create(uriBuilder.addParameter("titles", title).build().toString())) - .GET() - .build(), - HttpResponse.BodyHandlers.ofString()) - .get() - .body()).get(); - } - - @NotNull - private static URIBuilder getUriBuilder() throws URISyntaxException { - URIBuilder uriBuilder = new URIBuilder(URL); - uriBuilder.addParameter("action", "query"); - uriBuilder.addParameter("prop", "links"); - uriBuilder.addParameter("pllimit", "max"); - uriBuilder.addParameter("format", "json"); - uriBuilder.addParameter("plnamespace", "titles"); - return uriBuilder; - } - - @NotNull - private static List parseLinks(WikiLinksResponse response) { - return response.getQuery().getPages().entrySet().iterator().next().getValue().getLinks() - .stream() - .map(Link::getTitle) - .toList(); - } } diff --git a/wikigame/executor/src/main/java/WikiGameSerialImpl.java b/wikigame/executor/src/main/java/WikiGameSerialImpl.java index 301f6b9..5600c83 100644 --- a/wikigame/executor/src/main/java/WikiGameSerialImpl.java +++ b/wikigame/executor/src/main/java/WikiGameSerialImpl.java @@ -2,6 +2,9 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.jetbrains.annotations.NotNull; import point.rar.model.*; +import point.rar.repository.WikiGame; +import point.rar.wiki.WikiRemoteDataSource; +import point.rar.wiki.WikiRemoteDataSourceImpl; import java.io.IOException; import java.net.URI; @@ -13,6 +16,8 @@ public class WikiGameSerialImpl implements WikiGame { private static final String URL = "https://ru.wikipedia.org/w/api.php"; + private final WikiRemoteDataSource wikiRemoteDataSource = new WikiRemoteDataSourceImpl(); + @NotNull @Override public List play(String startPageTitle, String endPageTitle, int maxDepth) { @@ -27,7 +32,7 @@ public List play(String startPageTitle, String endPageTitle, int maxDept System.out.println("parsedTitle size = " + parsedTitle.size()); var curPage = rawPages.poll(); parentEndPage = curPage; - var newLinks = parseLinks(curPage.getTitle()); + var newLinks = wikiRemoteDataSource.getLinksByTitle(curPage.getTitle()); parsedPages.add(curPage); parsedTitle.addAll(newLinks); rawPages.addAll( @@ -54,32 +59,4 @@ private List getResultPath(Queue parsedPages, String endPageTitle) path.add(curPage.getTitle()); return path; } - - - private List parseLinks(String title) { - ObjectMapper objectMapper = new ObjectMapper(); - objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - try { - System.out.println("Get links for: " + title); - String responseBody = HttpClient.newBuilder() - .build() - .send(HttpRequest.newBuilder() - .uri(URI.create(URL + "?action=query&prop=links&pllimit=max&format=json&plnamespace=0&titles=" + title.replace(" ", "%20"))) - .GET() - .build(), HttpResponse.BodyHandlers.ofString()).body(); - WikiLinksResponse response = objectMapper.readValue(responseBody, WikiLinksResponse.class); - - return parseLinks(response); - } catch (IOException | InterruptedException e) { - throw new RuntimeException(e); - } - } - - @NotNull - private static List parseLinks(WikiLinksResponse response) { - return response.getQuery().getPages().entrySet().iterator().next().getValue().getLinks() - .stream() - .map(Link::getTitle) - .toList(); - } } diff --git a/wikigame/src/main/java/point/rar/repository/WikiGame.java b/wikigame/src/main/java/point/rar/repository/WikiGame.java new file mode 100644 index 0000000..fbf0b82 --- /dev/null +++ b/wikigame/src/main/java/point/rar/repository/WikiGame.java @@ -0,0 +1,7 @@ +package point.rar.repository; + +import java.util.List; + +public interface WikiGame { + List play(String startPageTitle, String endPageTitle, int maxDepth); +} diff --git a/wikigame/src/main/java/point/rar/wiki/WikiRemoteDataSource.java b/wikigame/src/main/java/point/rar/wiki/WikiRemoteDataSource.java new file mode 100644 index 0000000..c1fe960 --- /dev/null +++ b/wikigame/src/main/java/point/rar/wiki/WikiRemoteDataSource.java @@ -0,0 +1,8 @@ +package point.rar.wiki; + +import java.util.List; + +public interface WikiRemoteDataSource { + List getLinksByTitle(String title); + List getBacklinksByTitle(String title); +} diff --git a/wikigame/src/main/java/point/rar/wiki/WikiRemoteDataSourceImpl.java b/wikigame/src/main/java/point/rar/wiki/WikiRemoteDataSourceImpl.java new file mode 100644 index 0000000..b419740 --- /dev/null +++ b/wikigame/src/main/java/point/rar/wiki/WikiRemoteDataSourceImpl.java @@ -0,0 +1,81 @@ +package point.rar.wiki; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import io.github.resilience4j.ratelimiter.RateLimiter; +import io.github.resilience4j.ratelimiter.RateLimiterConfig; +import io.github.resilience4j.ratelimiter.RateLimiterRegistry; +import org.apache.http.client.utils.URIBuilder; +import org.jetbrains.annotations.NotNull; +import point.rar.model.Link; +import point.rar.model.WikiLinksResponse; + +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; +import java.util.List; + +public class WikiRemoteDataSourceImpl implements WikiRemoteDataSource { + private static final String URL = "https://ru.wikipedia.org/w/api.php"; + + private static final RateLimiterConfig config = RateLimiterConfig.custom() + .limitRefreshPeriod(Duration.ofMillis(40)) + .limitForPeriod(1) + .timeoutDuration(Duration.ofDays(100000)) + .build(); + private static final RateLimiterRegistry rateLimiterRegistry = RateLimiterRegistry.of(config); + private static final RateLimiter rateLimiter = rateLimiterRegistry.rateLimiter("rate"); + private static final ObjectMapper objectMapper = new ObjectMapper() + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + + @Override + public List getLinksByTitle(String title) { + try { + String responseBody = RateLimiter.decorateCheckedSupplier(rateLimiter, () -> + HttpClient.newBuilder() + .build() + .send( + HttpRequest.newBuilder() + .uri(getUriBuilder(title).build()) + .GET() + .build(), + HttpResponse.BodyHandlers.ofString() + ) + .body() + ).get(); + System.out.println("Got links from: " + title); + WikiLinksResponse response = objectMapper.readValue(responseBody, WikiLinksResponse.class); + + return parseResponse(response); + } catch (Throwable e) { + throw new RuntimeException(e); + } + } + + @NotNull + private static URIBuilder getUriBuilder(String title) throws URISyntaxException { + URIBuilder uriBuilder = new URIBuilder(URL); + uriBuilder.addParameter("action", "query"); + uriBuilder.addParameter("prop", "links"); + uriBuilder.addParameter("pllimit", "max"); + uriBuilder.addParameter("format", "json"); + uriBuilder.addParameter("plnamespace", "titles"); + uriBuilder.addParameter("titles", title); + return uriBuilder; + } + + @NotNull + private static List parseResponse(WikiLinksResponse response) { + return response.getQuery().getPages().entrySet().iterator().next().getValue().getLinks() + .stream() + .map(Link::getTitle) + .toList(); + } + + @Override + public List getBacklinksByTitle(String title) { + return null; + } +} From 438f2f34f41286c4edc6a9ca36436bdb04f441a8 Mon Sep 17 00:00:00 2001 From: Daniil Lyubaev Date: Thu, 7 Sep 2023 16:50:17 +0300 Subject: [PATCH 33/58] algo two way --- wikigame/algo/src/main/java/Main.kt | 12 + .../algo/src/main/java/model/BackwardPage.kt | 3 + .../algo/src/main/java/model/ForwardPage.kt | 3 + .../main/java/repository/WikiGameAlgoImpl.kt | 208 ++++++++++++++++++ wikigame/build.gradle.kts | 17 +- wikigame/coroutines/build.gradle.kts | 15 -- .../coroutines/repository/WikiGameCoroImpl.kt | 4 +- wikigame/settings.gradle.kts | 1 + .../rar/wikisuspend}/WikiRemoteDataSource.kt | 2 +- .../wikisuspend}/WikiRemoteDataSourceImpl.kt | 2 +- 10 files changed, 246 insertions(+), 21 deletions(-) create mode 100644 wikigame/algo/src/main/java/Main.kt create mode 100644 wikigame/algo/src/main/java/model/BackwardPage.kt create mode 100644 wikigame/algo/src/main/java/model/ForwardPage.kt create mode 100644 wikigame/algo/src/main/java/repository/WikiGameAlgoImpl.kt rename wikigame/{coroutines/src/main/java/coroutines/wiki => src/main/java/point/rar/wikisuspend}/WikiRemoteDataSource.kt (84%) rename wikigame/{coroutines/src/main/java/coroutines/wiki => src/main/java/point/rar/wikisuspend}/WikiRemoteDataSourceImpl.kt (98%) diff --git a/wikigame/algo/src/main/java/Main.kt b/wikigame/algo/src/main/java/Main.kt new file mode 100644 index 0000000..de3d939 --- /dev/null +++ b/wikigame/algo/src/main/java/Main.kt @@ -0,0 +1,12 @@ +import point.rar.repository.WikiGame +import repository.WikiGameAlgoImpl + +fun main(args: Array) { + val wikiGame: WikiGame = WikiGameAlgoImpl() + + val start = System.nanoTime() + val path = wikiGame.play("Бакуган", "Библия", 6) + val timeSec = (System.nanoTime() - start) / (1_000_000_000f) + println("$timeSec s.") + println(path) +} \ No newline at end of file diff --git a/wikigame/algo/src/main/java/model/BackwardPage.kt b/wikigame/algo/src/main/java/model/BackwardPage.kt new file mode 100644 index 0000000..55bc589 --- /dev/null +++ b/wikigame/algo/src/main/java/model/BackwardPage.kt @@ -0,0 +1,3 @@ +package model + +data class BackwardPage(val title: String, val childPage: BackwardPage?) diff --git a/wikigame/algo/src/main/java/model/ForwardPage.kt b/wikigame/algo/src/main/java/model/ForwardPage.kt new file mode 100644 index 0000000..1f62bfe --- /dev/null +++ b/wikigame/algo/src/main/java/model/ForwardPage.kt @@ -0,0 +1,3 @@ +package model + +data class ForwardPage(val title: String, val parentPage: ForwardPage?) diff --git a/wikigame/algo/src/main/java/repository/WikiGameAlgoImpl.kt b/wikigame/algo/src/main/java/repository/WikiGameAlgoImpl.kt new file mode 100644 index 0000000..d700d71 --- /dev/null +++ b/wikigame/algo/src/main/java/repository/WikiGameAlgoImpl.kt @@ -0,0 +1,208 @@ +package repository + +import kotlinx.coroutines.* +import kotlinx.coroutines.channels.Channel +import model.BackwardPage +import model.ForwardPage +import point.rar.model.Page +import point.rar.repository.WikiGame +import point.rar.wikisuspend.WikiRemoteDataSource +import point.rar.wikisuspend.WikiRemoteDataSourceImpl +import java.lang.RuntimeException +import java.util.* +import java.util.concurrent.ConcurrentHashMap + +class WikiGameAlgoImpl : WikiGame { + + private val wikiRemoteDataSource: WikiRemoteDataSource = WikiRemoteDataSourceImpl() + override fun play(startPageTitle: String, endPageTitle: String, maxDepth: Int): List { + val res = process(startPageTitle, endPageTitle, maxDepth) + if (res.isEmpty) { + throw RuntimeException("Could not find") + } + + val endPage = res.get() + val path = mutableListOf() + + var curPg: Page? = endPage + do { + path.add(curPg!!.title) + curPg = curPg.parentPage + } while (curPg != null) + +// val pagesWithResponseCount = visitedPages.entries.count { it.value == RESPONSE_RECEIVED } +// println("Received responses from $pagesWithResponseCount pages") + + return path.reversed() + } + + private fun process( + startPageTitle: String, + endPageTitle: String, + maxDepth: Int, + ): Optional = runBlocking { + val visitedForwardPages: MutableMap = ConcurrentHashMap() + val visitedBackwardPages: MutableMap = ConcurrentHashMap() + val ctx = newFixedThreadPoolContext(4, "fixed-thread-context") + val scope = CoroutineScope(ctx) + + val startForwardPage = ForwardPage(startPageTitle, null) + val endBackwardPage = BackwardPage(endPageTitle, null) + + val ch = Channel>>() + + scope.launch { + val res = processPageForward(startForwardPage, endPageTitle, 0, maxDepth, visitedForwardPages, visitedBackwardPages, scope) + ch.send(res) + } + scope.launch { + val res = processPageBackward(endBackwardPage, endPageTitle, 0, maxDepth, visitedForwardPages, visitedBackwardPages, scope) + ch.send(res) + } + + for (i in 1..2) { + val res = ch.receive() + if (res.isPresent) { + val pair = res.get() + return@runBlocking Optional.of(getFinalPageFromForwardAndBackward(pair.first, pair.second)) + } + } + + return@runBlocking Optional.empty() + } + + private suspend fun processPageForward( + page: ForwardPage, + endPageTitle: String, + curDepth: Int, + maxDepth: Int, + visitedForwardPages: MutableMap, + visitedBackwardPages: MutableMap, + coroutineScope: CoroutineScope + ): Optional> { + if (visitedForwardPages.putIfAbsent(page.title, page) != null) { + return Optional.empty() + } + + val backwardPage = visitedBackwardPages[page.title] + if (backwardPage != null) { + return Optional.of(Pair(page, backwardPage)) + } + + if (curDepth == maxDepth) { + return Optional.empty() + } + +// println("Started for ${page.title}, depth = $curDepth") + val links = wikiRemoteDataSource.getLinksByTitle(page.title) + + val ch = Channel>>() + + links.forEach { + // Creates new scope because we don't want to wait for all the coroutines to complete + coroutineScope.launch { + val coroRes = processPageForward( + ForwardPage(it, page), + endPageTitle, + curDepth + 1, + maxDepth, + visitedForwardPages, + visitedBackwardPages, + coroutineScope + ) + + ch.send(coroRes) + } + } + + for (i in 1..links.size) { + val chRes = ch.receive() + if (chRes.isPresent) { + return chRes + } + } + + return Optional.empty() + } + + private suspend fun processPageBackward( + page: BackwardPage, + endPageTitle: String, + curDepth: Int, + maxDepth: Int, + visitedForwardPages: MutableMap, + visitedBackwardPages: MutableMap, + coroutineScope: CoroutineScope + ): Optional> { + if (visitedBackwardPages.putIfAbsent(page.title, page) != null) { + return Optional.empty() + } + + val forwardPage = visitedForwardPages[page.title] + if (forwardPage != null) { + return Optional.of(Pair(forwardPage, page)) + } + + if (curDepth == maxDepth) { + return Optional.empty() + } + +// println("Started for ${page.title}, depth = $curDepth") + val backlinks = wikiRemoteDataSource.getBacklinksByTitle(page.title) + + val ch = Channel>>() + + backlinks.forEach { + // Creates new scope because we don't want to wait for all the coroutines to complete + coroutineScope.launch { + val coroRes = processPageBackward( + BackwardPage(it, page), + endPageTitle, + curDepth + 1, + maxDepth, + visitedForwardPages, + visitedBackwardPages, + coroutineScope + ) + + ch.send(coroRes) + } + } + + for (i in 1..backlinks.size) { + val chRes = ch.receive() + if (chRes.isPresent) { + return chRes + } + } + + return Optional.empty() + } + + fun getFinalPageFromForwardAndBackward(forwardPage: ForwardPage, backwardPage: BackwardPage): Page { + val forwardPages = mutableListOf() + var curFwdPage: ForwardPage? = forwardPage + do { + forwardPages.add(curFwdPage!!) + curFwdPage = curFwdPage.parentPage + } while(curFwdPage != null) + + var lastPage: Page? = null + for (fwdPg in forwardPages.reversed()) { + lastPage = Page(fwdPg.title, lastPage) + } + + val backwardPages = mutableListOf() + var curBwdPage: BackwardPage? = backwardPage + do { + backwardPages.add(curBwdPage!!) + curBwdPage = curBwdPage.childPage + } while(curBwdPage != null) + + for (bwdPg in backwardPages) { + lastPage = Page(bwdPg.title, lastPage) + } + + return lastPage!! + } +} \ No newline at end of file diff --git a/wikigame/build.gradle.kts b/wikigame/build.gradle.kts index e7f38e0..148bc1b 100644 --- a/wikigame/build.gradle.kts +++ b/wikigame/build.gradle.kts @@ -22,8 +22,21 @@ dependencies { implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.14.2") implementation("org.apache.httpcomponents:httpclient:4.5.13") - implementation("io.github.resilience4j:resilience4j-timelimiter:2.1.0") - implementation("io.github.resilience4j:resilience4j-ratelimiter:2.1.0") + val ktor_version = "2.2.3" + implementation("io.ktor:ktor-client-core:$ktor_version") + implementation("io.ktor:ktor-client-cio:$ktor_version") + implementation("io.ktor:ktor-client-content-negotiation:$ktor_version") + implementation("io.ktor:ktor-serialization-kotlinx-json:$ktor_version") + + val slf4j_version = "2.0.6" + implementation("org.slf4j:slf4j-api:$slf4j_version") + implementation("org.slf4j:slf4j-simple:$slf4j_version") + + val resilience4jVersion = "2.1.0" + implementation("io.github.resilience4j:resilience4j-kotlin:${resilience4jVersion}") + implementation("io.github.resilience4j:resilience4j-retry:${resilience4jVersion}") + implementation("io.github.resilience4j:resilience4j-timelimiter:${resilience4jVersion}") + implementation("io.github.resilience4j:resilience4j-ratelimiter:${resilience4jVersion}") } tasks.test { diff --git a/wikigame/coroutines/build.gradle.kts b/wikigame/coroutines/build.gradle.kts index 1858fcc..242b64b 100644 --- a/wikigame/coroutines/build.gradle.kts +++ b/wikigame/coroutines/build.gradle.kts @@ -17,21 +17,6 @@ dependencies { implementation(kotlin("stdlib-jdk8")) implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3") - - val ktor_version = "2.2.3" - implementation("io.ktor:ktor-client-core:$ktor_version") - implementation("io.ktor:ktor-client-cio:$ktor_version") - implementation("io.ktor:ktor-client-content-negotiation:$ktor_version") - implementation("io.ktor:ktor-serialization-kotlinx-json:$ktor_version") - - val slf4j_version = "2.0.6" - implementation("org.slf4j:slf4j-api:$slf4j_version") - implementation("org.slf4j:slf4j-simple:$slf4j_version") - - val resilience4jVersion = "2.0.0" - implementation("io.github.resilience4j:resilience4j-kotlin:${resilience4jVersion}") - implementation("io.github.resilience4j:resilience4j-ratelimiter:${resilience4jVersion}") - implementation("io.github.resilience4j:resilience4j-retry:${resilience4jVersion}") } tasks.test { diff --git a/wikigame/coroutines/src/main/java/coroutines/repository/WikiGameCoroImpl.kt b/wikigame/coroutines/src/main/java/coroutines/repository/WikiGameCoroImpl.kt index caeee37..efbe918 100644 --- a/wikigame/coroutines/src/main/java/coroutines/repository/WikiGameCoroImpl.kt +++ b/wikigame/coroutines/src/main/java/coroutines/repository/WikiGameCoroImpl.kt @@ -2,8 +2,8 @@ package coroutines.repository import kotlinx.coroutines.* import kotlinx.coroutines.channels.Channel -import coroutines.wiki.WikiRemoteDataSource -import coroutines.wiki.WikiRemoteDataSourceImpl +import point.rar.wikisuspend.WikiRemoteDataSource +import point.rar.wikisuspend.WikiRemoteDataSourceImpl import point.rar.model.Page import point.rar.repository.WikiGame import java.lang.RuntimeException diff --git a/wikigame/settings.gradle.kts b/wikigame/settings.gradle.kts index a80f656..674e82e 100644 --- a/wikigame/settings.gradle.kts +++ b/wikigame/settings.gradle.kts @@ -5,3 +5,4 @@ rootProject.name = "wikigame" include("coroutines") include("executor") include("completable-future") +include("algo") diff --git a/wikigame/coroutines/src/main/java/coroutines/wiki/WikiRemoteDataSource.kt b/wikigame/src/main/java/point/rar/wikisuspend/WikiRemoteDataSource.kt similarity index 84% rename from wikigame/coroutines/src/main/java/coroutines/wiki/WikiRemoteDataSource.kt rename to wikigame/src/main/java/point/rar/wikisuspend/WikiRemoteDataSource.kt index 67f6c91..0313113 100644 --- a/wikigame/coroutines/src/main/java/coroutines/wiki/WikiRemoteDataSource.kt +++ b/wikigame/src/main/java/point/rar/wikisuspend/WikiRemoteDataSource.kt @@ -1,4 +1,4 @@ -package coroutines.wiki +package point.rar.wikisuspend interface WikiRemoteDataSource { suspend fun getLinksByTitle(title: String): List diff --git a/wikigame/coroutines/src/main/java/coroutines/wiki/WikiRemoteDataSourceImpl.kt b/wikigame/src/main/java/point/rar/wikisuspend/WikiRemoteDataSourceImpl.kt similarity index 98% rename from wikigame/coroutines/src/main/java/coroutines/wiki/WikiRemoteDataSourceImpl.kt rename to wikigame/src/main/java/point/rar/wikisuspend/WikiRemoteDataSourceImpl.kt index acc37b2..a4837ed 100644 --- a/wikigame/coroutines/src/main/java/coroutines/wiki/WikiRemoteDataSourceImpl.kt +++ b/wikigame/src/main/java/point/rar/wikisuspend/WikiRemoteDataSourceImpl.kt @@ -1,4 +1,4 @@ -package coroutines.wiki +package point.rar.wikisuspend import io.github.resilience4j.kotlin.ratelimiter.executeSuspendFunction import io.github.resilience4j.ratelimiter.RateLimiterConfig From 365543f5517fab12f95fdfc5a98b49d01d03e277 Mon Sep 17 00:00:00 2001 From: Daniil Lyubaev Date: Thu, 7 Sep 2023 16:59:56 +0300 Subject: [PATCH 34/58] fix page repeat --- wikigame/algo/src/main/java/repository/WikiGameAlgoImpl.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wikigame/algo/src/main/java/repository/WikiGameAlgoImpl.kt b/wikigame/algo/src/main/java/repository/WikiGameAlgoImpl.kt index d700d71..da2a4bc 100644 --- a/wikigame/algo/src/main/java/repository/WikiGameAlgoImpl.kt +++ b/wikigame/algo/src/main/java/repository/WikiGameAlgoImpl.kt @@ -193,7 +193,7 @@ class WikiGameAlgoImpl : WikiGame { } val backwardPages = mutableListOf() - var curBwdPage: BackwardPage? = backwardPage + var curBwdPage: BackwardPage? = backwardPage.childPage do { backwardPages.add(curBwdPage!!) curBwdPage = curBwdPage.childPage From cd8f3e78c38ee7741b93c998f7512f2b4099097e Mon Sep 17 00:00:00 2001 From: Daniil Lyubaev Date: Fri, 8 Sep 2023 12:03:21 +0300 Subject: [PATCH 35/58] limiter + fix --- .../main/java/repository/WikiGameAlgoImpl.kt | 34 ++++++++++++++----- .../wikisuspend/WikiRemoteDataSourceImpl.kt | 18 +++++----- 2 files changed, 35 insertions(+), 17 deletions(-) diff --git a/wikigame/algo/src/main/java/repository/WikiGameAlgoImpl.kt b/wikigame/algo/src/main/java/repository/WikiGameAlgoImpl.kt index da2a4bc..b6cfe96 100644 --- a/wikigame/algo/src/main/java/repository/WikiGameAlgoImpl.kt +++ b/wikigame/algo/src/main/java/repository/WikiGameAlgoImpl.kt @@ -52,11 +52,27 @@ class WikiGameAlgoImpl : WikiGame { val ch = Channel>>() scope.launch { - val res = processPageForward(startForwardPage, endPageTitle, 0, maxDepth, visitedForwardPages, visitedBackwardPages, scope) + val res = processPageForward( + startForwardPage, + endPageTitle, + 0, + maxDepth, + visitedForwardPages, + visitedBackwardPages, + scope + ) ch.send(res) } scope.launch { - val res = processPageBackward(endBackwardPage, endPageTitle, 0, maxDepth, visitedForwardPages, visitedBackwardPages, scope) + val res = processPageBackward( + endBackwardPage, + endPageTitle, + 0, + maxDepth, + visitedForwardPages, + visitedBackwardPages, + scope + ) ch.send(res) } @@ -179,13 +195,13 @@ class WikiGameAlgoImpl : WikiGame { return Optional.empty() } - fun getFinalPageFromForwardAndBackward(forwardPage: ForwardPage, backwardPage: BackwardPage): Page { + private fun getFinalPageFromForwardAndBackward(forwardPage: ForwardPage, backwardPage: BackwardPage): Page { val forwardPages = mutableListOf() var curFwdPage: ForwardPage? = forwardPage - do { - forwardPages.add(curFwdPage!!) + while (curFwdPage != null) { + forwardPages.add(curFwdPage) curFwdPage = curFwdPage.parentPage - } while(curFwdPage != null) + } var lastPage: Page? = null for (fwdPg in forwardPages.reversed()) { @@ -194,10 +210,10 @@ class WikiGameAlgoImpl : WikiGame { val backwardPages = mutableListOf() var curBwdPage: BackwardPage? = backwardPage.childPage - do { - backwardPages.add(curBwdPage!!) + while (curBwdPage != null) { + backwardPages.add(curBwdPage) curBwdPage = curBwdPage.childPage - } while(curBwdPage != null) + } for (bwdPg in backwardPages) { lastPage = Page(bwdPg.title, lastPage) diff --git a/wikigame/src/main/java/point/rar/wikisuspend/WikiRemoteDataSourceImpl.kt b/wikigame/src/main/java/point/rar/wikisuspend/WikiRemoteDataSourceImpl.kt index a4837ed..4fa4065 100644 --- a/wikigame/src/main/java/point/rar/wikisuspend/WikiRemoteDataSourceImpl.kt +++ b/wikigame/src/main/java/point/rar/wikisuspend/WikiRemoteDataSourceImpl.kt @@ -67,16 +67,18 @@ class WikiRemoteDataSourceImpl : WikiRemoteDataSource { } override suspend fun getBacklinksByTitle(title: String): List { - val request = client.get(URL) { - parameter("action", "query") - parameter("bltitle", title) - parameter("list", "backlinks") - parameter("bllimit", "max") - parameter("format", "json") - parameter("blnamespace", 0) + val response = rateLimiter.executeSuspendFunction { + client.get(URL) { + parameter("action", "query") + parameter("bltitle", title) + parameter("list", "backlinks") + parameter("bllimit", "max") + parameter("format", "json") + parameter("blnamespace", 0) + } } - val wikiBacklinksResponse: WikiBacklinksResponse = request.body() + val wikiBacklinksResponse: WikiBacklinksResponse = response.body() return wikiBacklinksResponse .query From f3e1c0fe7d66719fd6b155e20b03362ab1e69246 Mon Sep 17 00:00:00 2001 From: Daniil Lyubaev Date: Fri, 8 Sep 2023 12:23:54 +0300 Subject: [PATCH 36/58] refactor --- .../main/java/repository/WikiGameAlgoImpl.kt | 36 ++++++------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/wikigame/algo/src/main/java/repository/WikiGameAlgoImpl.kt b/wikigame/algo/src/main/java/repository/WikiGameAlgoImpl.kt index b6cfe96..14d351f 100644 --- a/wikigame/algo/src/main/java/repository/WikiGameAlgoImpl.kt +++ b/wikigame/algo/src/main/java/repository/WikiGameAlgoImpl.kt @@ -4,7 +4,6 @@ import kotlinx.coroutines.* import kotlinx.coroutines.channels.Channel import model.BackwardPage import model.ForwardPage -import point.rar.model.Page import point.rar.repository.WikiGame import point.rar.wikisuspend.WikiRemoteDataSource import point.rar.wikisuspend.WikiRemoteDataSourceImpl @@ -16,31 +15,22 @@ class WikiGameAlgoImpl : WikiGame { private val wikiRemoteDataSource: WikiRemoteDataSource = WikiRemoteDataSourceImpl() override fun play(startPageTitle: String, endPageTitle: String, maxDepth: Int): List { - val res = process(startPageTitle, endPageTitle, maxDepth) - if (res.isEmpty) { + val pathOpt = process(startPageTitle, endPageTitle, maxDepth) + if (pathOpt.isEmpty) { throw RuntimeException("Could not find") } - val endPage = res.get() - val path = mutableListOf() - - var curPg: Page? = endPage - do { - path.add(curPg!!.title) - curPg = curPg.parentPage - } while (curPg != null) - // val pagesWithResponseCount = visitedPages.entries.count { it.value == RESPONSE_RECEIVED } // println("Received responses from $pagesWithResponseCount pages") - return path.reversed() + return pathOpt.get() } private fun process( startPageTitle: String, endPageTitle: String, maxDepth: Int, - ): Optional = runBlocking { + ): Optional> = runBlocking { val visitedForwardPages: MutableMap = ConcurrentHashMap() val visitedBackwardPages: MutableMap = ConcurrentHashMap() val ctx = newFixedThreadPoolContext(4, "fixed-thread-context") @@ -80,7 +70,7 @@ class WikiGameAlgoImpl : WikiGame { val res = ch.receive() if (res.isPresent) { val pair = res.get() - return@runBlocking Optional.of(getFinalPageFromForwardAndBackward(pair.first, pair.second)) + return@runBlocking Optional.of(getFinalPathFromForwardAndBackward(pair.first, pair.second)) } } @@ -195,7 +185,9 @@ class WikiGameAlgoImpl : WikiGame { return Optional.empty() } - private fun getFinalPageFromForwardAndBackward(forwardPage: ForwardPage, backwardPage: BackwardPage): Page { + private fun getFinalPathFromForwardAndBackward(forwardPage: ForwardPage, backwardPage: BackwardPage): List { + val path = mutableListOf() + val forwardPages = mutableListOf() var curFwdPage: ForwardPage? = forwardPage while (curFwdPage != null) { @@ -203,22 +195,16 @@ class WikiGameAlgoImpl : WikiGame { curFwdPage = curFwdPage.parentPage } - var lastPage: Page? = null for (fwdPg in forwardPages.reversed()) { - lastPage = Page(fwdPg.title, lastPage) + path.add(fwdPg.title) } - val backwardPages = mutableListOf() var curBwdPage: BackwardPage? = backwardPage.childPage while (curBwdPage != null) { - backwardPages.add(curBwdPage) + path.add(curBwdPage.title) curBwdPage = curBwdPage.childPage } - for (bwdPg in backwardPages) { - lastPage = Page(bwdPg.title, lastPage) - } - - return lastPage!! + return path } } \ No newline at end of file From 99dc5f99aa6891535916b7254bc2a9ad380a8821 Mon Sep 17 00:00:00 2001 From: Daniil Lyubaev Date: Fri, 8 Sep 2023 16:28:32 +0300 Subject: [PATCH 37/58] one module --- .gitignore | 5 +++ wikigame/build.gradle.kts => build.gradle.kts | 10 ++++++ wikigame/gradlew => gradlew | 30 +++++++++++----- wikigame/gradlew.bat => gradlew.bat | 15 ++++---- ...settings.gradle.kts => settings.gradle.kts | 2 +- .../main/java/rar/java/Main.java | 8 +++-- .../java/rar/java}/repository/WikiGame.java | 2 +- .../repository}/WikiGameExecutorImpl.java | 9 ++--- .../java/repository}/WikiGameFutureImpl.java | 9 ++--- .../repository}/WikiGameFutureSimpleImpl.java | 7 ++-- .../java/repository}/WikiGameSerialImpl.java | 16 +++------ .../rar/java}/wiki/WikiRemoteDataSource.java | 2 +- .../java}/wiki/WikiRemoteDataSourceImpl.java | 6 ++-- .../main/kotlin/rar/kotlin}/Main.kt | 8 +++-- .../kotlin/rar/kotlin}/model/BackwardPage.kt | 2 +- .../kotlin/rar/kotlin}/model/ForwardPage.kt | 2 +- .../main/kotlin/rar/kotlin}/model/Link.kt | 2 +- .../main/kotlin/rar/kotlin}/model/Page.kt | 2 +- .../kotlin/rar/kotlin}/model/PageLinks.kt | 2 +- .../rar/kotlin}/model/QueryBacklinks.kt | 4 +-- .../kotlin/rar/kotlin}/model/QueryLinks.kt | 2 +- .../kotlin}/model/WikiBacklinksResponse.kt | 4 +-- .../rar/kotlin}/model/WikiLinksResponse.kt | 2 +- .../kotlin}/repository/WikiGameAlgoImpl.kt | 10 +++--- .../kotlin}/repository/WikiGameCoroImpl.kt | 8 ++--- .../rar/kotlin/wiki}/WikiRemoteDataSource.kt | 2 +- .../kotlin/wiki}/WikiRemoteDataSourceImpl.kt | 6 ++-- wikigame/.gitignore | 4 --- wikigame/algo/src/main/java/Main.kt | 12 ------- wikigame/completable-future/build.gradle.kts | 34 ------------------- .../src/main/java/MainFuture.java | 13 ------- wikigame/coroutines/build.gradle.kts | 27 --------------- wikigame/executor/build.gradle.kts | 34 ------------------- .../gradle/wrapper/gradle-wrapper.properties | 6 ---- wikigame/src/main/java/point/rar/Main.java | 7 ---- 35 files changed, 107 insertions(+), 207 deletions(-) rename wikigame/build.gradle.kts => build.gradle.kts (77%) rename wikigame/gradlew => gradlew (91%) rename wikigame/gradlew.bat => gradlew.bat (86%) rename wikigame/settings.gradle.kts => settings.gradle.kts (80%) rename wikigame/executor/src/main/java/MainExecutor.java => src/main/java/rar/java/Main.java (73%) rename {wikigame/src/main/java/point/rar => src/main/java/rar/java}/repository/WikiGame.java (81%) rename {wikigame/executor/src/main/java => src/main/java/rar/java/repository}/WikiGameExecutorImpl.java (94%) rename {wikigame/completable-future/src/main/java => src/main/java/rar/java/repository}/WikiGameFutureImpl.java (95%) rename {wikigame/completable-future/src/main/java => src/main/java/rar/java/repository}/WikiGameFutureSimpleImpl.java (97%) rename {wikigame/executor/src/main/java => src/main/java/rar/java/repository}/WikiGameSerialImpl.java (82%) rename {wikigame/src/main/java/point/rar => src/main/java/rar/java}/wiki/WikiRemoteDataSource.java (87%) rename {wikigame/src/main/java/point/rar => src/main/java/rar/java}/wiki/WikiRemoteDataSourceImpl.java (97%) rename {wikigame/coroutines/src/main/java/coroutines => src/main/kotlin/rar/kotlin}/Main.kt (78%) rename {wikigame/algo/src/main/java => src/main/kotlin/rar/kotlin}/model/BackwardPage.kt (74%) rename {wikigame/algo/src/main/java => src/main/kotlin/rar/kotlin}/model/ForwardPage.kt (74%) rename {wikigame/src/main/java/point/rar => src/main/kotlin/rar/kotlin}/model/Link.kt (80%) rename {wikigame/src/main/java/point/rar => src/main/kotlin/rar/kotlin}/model/Page.kt (87%) rename {wikigame/src/main/java/point/rar => src/main/kotlin/rar/kotlin}/model/PageLinks.kt (83%) rename {wikigame/src/main/java/point/rar => src/main/kotlin/rar/kotlin}/model/QueryBacklinks.kt (59%) rename {wikigame/src/main/java/point/rar => src/main/kotlin/rar/kotlin}/model/QueryLinks.kt (84%) rename {wikigame/src/main/java/point/rar => src/main/kotlin/rar/kotlin}/model/WikiBacklinksResponse.kt (61%) rename {wikigame/src/main/java/point/rar => src/main/kotlin/rar/kotlin}/model/WikiLinksResponse.kt (84%) rename {wikigame/algo/src/main/java => src/main/kotlin/rar/kotlin}/repository/WikiGameAlgoImpl.kt (96%) rename {wikigame/coroutines/src/main/java/coroutines => src/main/kotlin/rar/kotlin}/repository/WikiGameCoroImpl.kt (94%) rename {wikigame/src/main/java/point/rar/wikisuspend => src/main/kotlin/rar/kotlin/wiki}/WikiRemoteDataSource.kt (84%) rename {wikigame/src/main/java/point/rar/wikisuspend => src/main/kotlin/rar/kotlin/wiki}/WikiRemoteDataSourceImpl.kt (95%) delete mode 100644 wikigame/.gitignore delete mode 100644 wikigame/algo/src/main/java/Main.kt delete mode 100644 wikigame/completable-future/build.gradle.kts delete mode 100644 wikigame/completable-future/src/main/java/MainFuture.java delete mode 100644 wikigame/coroutines/build.gradle.kts delete mode 100644 wikigame/executor/build.gradle.kts delete mode 100644 wikigame/gradle/wrapper/gradle-wrapper.properties delete mode 100644 wikigame/src/main/java/point/rar/Main.java diff --git a/.gitignore b/.gitignore index c01f7ed..8baed0d 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,8 @@ hs_err_pid* .idea* +.gradle* +build* +build/* +gradle + diff --git a/wikigame/build.gradle.kts b/build.gradle.kts similarity index 77% rename from wikigame/build.gradle.kts rename to build.gradle.kts index 148bc1b..963efaf 100644 --- a/wikigame/build.gradle.kts +++ b/build.gradle.kts @@ -16,6 +16,8 @@ dependencies { testImplementation("org.junit.jupiter:junit-jupiter") implementation(kotlin("stdlib-jdk8")) + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3") + val kotlinx_serialization_json_version = "1.4.1" implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinx_serialization_json_version") @@ -37,11 +39,19 @@ dependencies { implementation("io.github.resilience4j:resilience4j-retry:${resilience4jVersion}") implementation("io.github.resilience4j:resilience4j-timelimiter:${resilience4jVersion}") implementation("io.github.resilience4j:resilience4j-ratelimiter:${resilience4jVersion}") + + implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.14.2") + implementation("org.apache.httpcomponents:httpclient:4.5.13") + implementation("io.github.resilience4j:resilience4j-timelimiter:2.1.0") + implementation("io.github.resilience4j:resilience4j-ratelimiter:2.1.0") } tasks.test { useJUnitPlatform() } +tasks.withType { + options.compilerArgs.add("--enable-preview") +} kotlin { jvmToolchain(19) } \ No newline at end of file diff --git a/wikigame/gradlew b/gradlew similarity index 91% rename from wikigame/gradlew rename to gradlew index 1b6c787..fcb6fca 100755 --- a/wikigame/gradlew +++ b/gradlew @@ -55,7 +55,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -80,13 +80,10 @@ do esac done -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" +# This is normally unused +# shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -133,22 +130,29 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -193,6 +197,10 @@ if "$cygwin" || "$msys" ; then done fi + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + # Collect all arguments for the java command; # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of # shell script including quotes and variable substitutions, so put them in @@ -205,6 +213,12 @@ set -- \ org.gradle.wrapper.GradleWrapperMain \ "$@" +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + # Use "xargs" to parse quoted args. # # With -n1 it outputs one arg per line, with the quotes and backslashes removed. diff --git a/wikigame/gradlew.bat b/gradlew.bat similarity index 86% rename from wikigame/gradlew.bat rename to gradlew.bat index ac1b06f..6689b85 100644 --- a/wikigame/gradlew.bat +++ b/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +25,8 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/wikigame/settings.gradle.kts b/settings.gradle.kts similarity index 80% rename from wikigame/settings.gradle.kts rename to settings.gradle.kts index 674e82e..537a11c 100644 --- a/wikigame/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,7 +1,7 @@ plugins { id("org.gradle.toolchains.foojay-resolver-convention") version "0.5.0" } -rootProject.name = "wikigame" +rootProject.name = "Thread-Wars-WikiGame" include("coroutines") include("executor") include("completable-future") diff --git a/wikigame/executor/src/main/java/MainExecutor.java b/src/main/java/rar/java/Main.java similarity index 73% rename from wikigame/executor/src/main/java/MainExecutor.java rename to src/main/java/rar/java/Main.java index c50e307..0e54aa6 100644 --- a/wikigame/executor/src/main/java/MainExecutor.java +++ b/src/main/java/rar/java/Main.java @@ -1,6 +1,10 @@ -import point.rar.repository.WikiGame; +package rar.java; -public class MainExecutor { +import rar.java.repository.WikiGame; +import rar.java.repository.WikiGameExecutorImpl; +import rar.java.repository.WikiGameFutureImpl; + +public class Main { public static void main(String[] args) { long startTime = System.currentTimeMillis(); WikiGame wikiGame = new WikiGameExecutorImpl(); diff --git a/wikigame/src/main/java/point/rar/repository/WikiGame.java b/src/main/java/rar/java/repository/WikiGame.java similarity index 81% rename from wikigame/src/main/java/point/rar/repository/WikiGame.java rename to src/main/java/rar/java/repository/WikiGame.java index fbf0b82..fe8e365 100644 --- a/wikigame/src/main/java/point/rar/repository/WikiGame.java +++ b/src/main/java/rar/java/repository/WikiGame.java @@ -1,4 +1,4 @@ -package point.rar.repository; +package rar.java.repository; import java.util.List; diff --git a/wikigame/executor/src/main/java/WikiGameExecutorImpl.java b/src/main/java/rar/java/repository/WikiGameExecutorImpl.java similarity index 94% rename from wikigame/executor/src/main/java/WikiGameExecutorImpl.java rename to src/main/java/rar/java/repository/WikiGameExecutorImpl.java index 9b38b9d..a623125 100644 --- a/wikigame/executor/src/main/java/WikiGameExecutorImpl.java +++ b/src/main/java/rar/java/repository/WikiGameExecutorImpl.java @@ -1,8 +1,9 @@ +package rar.java.repository; + import org.jetbrains.annotations.NotNull; -import point.rar.model.*; -import point.rar.repository.WikiGame; -import point.rar.wiki.WikiRemoteDataSource; -import point.rar.wiki.WikiRemoteDataSourceImpl; +import rar.java.wiki.WikiRemoteDataSource; +import rar.java.wiki.WikiRemoteDataSourceImpl; +import rar.kotlin.model.Page; import java.util.*; import java.util.concurrent.*; diff --git a/wikigame/completable-future/src/main/java/WikiGameFutureImpl.java b/src/main/java/rar/java/repository/WikiGameFutureImpl.java similarity index 95% rename from wikigame/completable-future/src/main/java/WikiGameFutureImpl.java rename to src/main/java/rar/java/repository/WikiGameFutureImpl.java index 5665544..90c69d2 100644 --- a/wikigame/completable-future/src/main/java/WikiGameFutureImpl.java +++ b/src/main/java/rar/java/repository/WikiGameFutureImpl.java @@ -1,10 +1,11 @@ +package rar.java.repository; + import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import org.jetbrains.annotations.NotNull; -import point.rar.model.*; -import point.rar.repository.WikiGame; -import point.rar.wiki.WikiRemoteDataSource; -import point.rar.wiki.WikiRemoteDataSourceImpl; +import rar.java.wiki.WikiRemoteDataSource; +import rar.java.wiki.WikiRemoteDataSourceImpl; +import rar.kotlin.model.Page; import java.util.*; import java.util.concurrent.*; diff --git a/wikigame/completable-future/src/main/java/WikiGameFutureSimpleImpl.java b/src/main/java/rar/java/repository/WikiGameFutureSimpleImpl.java similarity index 97% rename from wikigame/completable-future/src/main/java/WikiGameFutureSimpleImpl.java rename to src/main/java/rar/java/repository/WikiGameFutureSimpleImpl.java index a033630..e48d3e8 100644 --- a/wikigame/completable-future/src/main/java/WikiGameFutureSimpleImpl.java +++ b/src/main/java/rar/java/repository/WikiGameFutureSimpleImpl.java @@ -1,3 +1,5 @@ +package rar.java.repository; + import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import io.github.resilience4j.ratelimiter.RateLimiter; @@ -5,8 +7,9 @@ import io.github.resilience4j.ratelimiter.RateLimiterRegistry; import org.apache.http.client.utils.URIBuilder; import org.jetbrains.annotations.NotNull; -import point.rar.model.*; -import point.rar.repository.WikiGame; +import rar.kotlin.model.Link; +import rar.kotlin.model.Page; +import rar.kotlin.model.WikiLinksResponse; import java.io.IOException; import java.net.URI; diff --git a/wikigame/executor/src/main/java/WikiGameSerialImpl.java b/src/main/java/rar/java/repository/WikiGameSerialImpl.java similarity index 82% rename from wikigame/executor/src/main/java/WikiGameSerialImpl.java rename to src/main/java/rar/java/repository/WikiGameSerialImpl.java index 5600c83..299d8b4 100644 --- a/wikigame/executor/src/main/java/WikiGameSerialImpl.java +++ b/src/main/java/rar/java/repository/WikiGameSerialImpl.java @@ -1,16 +1,10 @@ -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; +package rar.java.repository; + import org.jetbrains.annotations.NotNull; -import point.rar.model.*; -import point.rar.repository.WikiGame; -import point.rar.wiki.WikiRemoteDataSource; -import point.rar.wiki.WikiRemoteDataSourceImpl; +import rar.java.wiki.WikiRemoteDataSource; +import rar.java.wiki.WikiRemoteDataSourceImpl; +import rar.kotlin.model.Page; -import java.io.IOException; -import java.net.URI; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; import java.util.*; public class WikiGameSerialImpl implements WikiGame { diff --git a/wikigame/src/main/java/point/rar/wiki/WikiRemoteDataSource.java b/src/main/java/rar/java/wiki/WikiRemoteDataSource.java similarity index 87% rename from wikigame/src/main/java/point/rar/wiki/WikiRemoteDataSource.java rename to src/main/java/rar/java/wiki/WikiRemoteDataSource.java index c1fe960..a87a8e4 100644 --- a/wikigame/src/main/java/point/rar/wiki/WikiRemoteDataSource.java +++ b/src/main/java/rar/java/wiki/WikiRemoteDataSource.java @@ -1,4 +1,4 @@ -package point.rar.wiki; +package rar.java.wiki; import java.util.List; diff --git a/wikigame/src/main/java/point/rar/wiki/WikiRemoteDataSourceImpl.java b/src/main/java/rar/java/wiki/WikiRemoteDataSourceImpl.java similarity index 97% rename from wikigame/src/main/java/point/rar/wiki/WikiRemoteDataSourceImpl.java rename to src/main/java/rar/java/wiki/WikiRemoteDataSourceImpl.java index b419740..f6fb0b1 100644 --- a/wikigame/src/main/java/point/rar/wiki/WikiRemoteDataSourceImpl.java +++ b/src/main/java/rar/java/wiki/WikiRemoteDataSourceImpl.java @@ -1,4 +1,4 @@ -package point.rar.wiki; +package rar.java.wiki; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; @@ -7,8 +7,8 @@ import io.github.resilience4j.ratelimiter.RateLimiterRegistry; import org.apache.http.client.utils.URIBuilder; import org.jetbrains.annotations.NotNull; -import point.rar.model.Link; -import point.rar.model.WikiLinksResponse; +import rar.kotlin.model.Link; +import rar.kotlin.model.WikiLinksResponse; import java.net.URISyntaxException; import java.net.http.HttpClient; diff --git a/wikigame/coroutines/src/main/java/coroutines/Main.kt b/src/main/kotlin/rar/kotlin/Main.kt similarity index 78% rename from wikigame/coroutines/src/main/java/coroutines/Main.kt rename to src/main/kotlin/rar/kotlin/Main.kt index ddc803b..6684ce2 100644 --- a/wikigame/coroutines/src/main/java/coroutines/Main.kt +++ b/src/main/kotlin/rar/kotlin/Main.kt @@ -1,7 +1,8 @@ -package coroutines +package rar.kotlin import coroutines.repository.WikiGameCoroImpl -import point.rar.repository.WikiGame +import rar.java.repository.WikiGame +import repository.WikiGameAlgoImpl fun main(args: Array) { val wikiGame: WikiGame = WikiGameCoroImpl() @@ -11,4 +12,5 @@ fun main(args: Array) { val timeSec = (System.nanoTime() - start) / (1_000_000_000f) println("$timeSec s.") println(path) -} \ No newline at end of file +} + diff --git a/wikigame/algo/src/main/java/model/BackwardPage.kt b/src/main/kotlin/rar/kotlin/model/BackwardPage.kt similarity index 74% rename from wikigame/algo/src/main/java/model/BackwardPage.kt rename to src/main/kotlin/rar/kotlin/model/BackwardPage.kt index 55bc589..ac01b2b 100644 --- a/wikigame/algo/src/main/java/model/BackwardPage.kt +++ b/src/main/kotlin/rar/kotlin/model/BackwardPage.kt @@ -1,3 +1,3 @@ -package model +package rar.kotlin.model data class BackwardPage(val title: String, val childPage: BackwardPage?) diff --git a/wikigame/algo/src/main/java/model/ForwardPage.kt b/src/main/kotlin/rar/kotlin/model/ForwardPage.kt similarity index 74% rename from wikigame/algo/src/main/java/model/ForwardPage.kt rename to src/main/kotlin/rar/kotlin/model/ForwardPage.kt index 1f62bfe..f7a1abf 100644 --- a/wikigame/algo/src/main/java/model/ForwardPage.kt +++ b/src/main/kotlin/rar/kotlin/model/ForwardPage.kt @@ -1,3 +1,3 @@ -package model +package rar.kotlin.model data class ForwardPage(val title: String, val parentPage: ForwardPage?) diff --git a/wikigame/src/main/java/point/rar/model/Link.kt b/src/main/kotlin/rar/kotlin/model/Link.kt similarity index 80% rename from wikigame/src/main/java/point/rar/model/Link.kt rename to src/main/kotlin/rar/kotlin/model/Link.kt index 7168dc8..ffcb82c 100644 --- a/wikigame/src/main/java/point/rar/model/Link.kt +++ b/src/main/kotlin/rar/kotlin/model/Link.kt @@ -1,4 +1,4 @@ -package point.rar.model +package rar.kotlin.model import kotlinx.serialization.Serializable diff --git a/wikigame/src/main/java/point/rar/model/Page.kt b/src/main/kotlin/rar/kotlin/model/Page.kt similarity index 87% rename from wikigame/src/main/java/point/rar/model/Page.kt rename to src/main/kotlin/rar/kotlin/model/Page.kt index f67a8e5..908c607 100644 --- a/wikigame/src/main/java/point/rar/model/Page.kt +++ b/src/main/kotlin/rar/kotlin/model/Page.kt @@ -1,4 +1,4 @@ -package point.rar.model +package rar.kotlin.model data class Page(val title: String, val parentPage: Page?) : Comparable { override fun compareTo(other: Page): Int { diff --git a/wikigame/src/main/java/point/rar/model/PageLinks.kt b/src/main/kotlin/rar/kotlin/model/PageLinks.kt similarity index 83% rename from wikigame/src/main/java/point/rar/model/PageLinks.kt rename to src/main/kotlin/rar/kotlin/model/PageLinks.kt index 693fe8a..8a1b20e 100644 --- a/wikigame/src/main/java/point/rar/model/PageLinks.kt +++ b/src/main/kotlin/rar/kotlin/model/PageLinks.kt @@ -1,4 +1,4 @@ -package point.rar.model +package rar.kotlin.model import kotlinx.serialization.Serializable diff --git a/wikigame/src/main/java/point/rar/model/QueryBacklinks.kt b/src/main/kotlin/rar/kotlin/model/QueryBacklinks.kt similarity index 59% rename from wikigame/src/main/java/point/rar/model/QueryBacklinks.kt rename to src/main/kotlin/rar/kotlin/model/QueryBacklinks.kt index efe2d87..6a11be0 100644 --- a/wikigame/src/main/java/point/rar/model/QueryBacklinks.kt +++ b/src/main/kotlin/rar/kotlin/model/QueryBacklinks.kt @@ -1,8 +1,8 @@ -package point.rar.model +package rar.kotlin.model import kotlinx.serialization.Serializable @Serializable data class QueryBacklinks( - val backlinks: List, + val backlinks: List, ) diff --git a/wikigame/src/main/java/point/rar/model/QueryLinks.kt b/src/main/kotlin/rar/kotlin/model/QueryLinks.kt similarity index 84% rename from wikigame/src/main/java/point/rar/model/QueryLinks.kt rename to src/main/kotlin/rar/kotlin/model/QueryLinks.kt index 4288c78..cfe64e3 100644 --- a/wikigame/src/main/java/point/rar/model/QueryLinks.kt +++ b/src/main/kotlin/rar/kotlin/model/QueryLinks.kt @@ -1,4 +1,4 @@ -package point.rar.model +package rar.kotlin.model import kotlinx.serialization.Serializable diff --git a/wikigame/src/main/java/point/rar/model/WikiBacklinksResponse.kt b/src/main/kotlin/rar/kotlin/model/WikiBacklinksResponse.kt similarity index 61% rename from wikigame/src/main/java/point/rar/model/WikiBacklinksResponse.kt rename to src/main/kotlin/rar/kotlin/model/WikiBacklinksResponse.kt index bf09bf6..3669b4b 100644 --- a/wikigame/src/main/java/point/rar/model/WikiBacklinksResponse.kt +++ b/src/main/kotlin/rar/kotlin/model/WikiBacklinksResponse.kt @@ -1,8 +1,8 @@ -package point.rar.model +package rar.kotlin.model import kotlinx.serialization.Serializable @Serializable data class WikiBacklinksResponse( - val query: QueryBacklinks, + val query: QueryBacklinks, ) diff --git a/wikigame/src/main/java/point/rar/model/WikiLinksResponse.kt b/src/main/kotlin/rar/kotlin/model/WikiLinksResponse.kt similarity index 84% rename from wikigame/src/main/java/point/rar/model/WikiLinksResponse.kt rename to src/main/kotlin/rar/kotlin/model/WikiLinksResponse.kt index 4eccdb0..4059298 100644 --- a/wikigame/src/main/java/point/rar/model/WikiLinksResponse.kt +++ b/src/main/kotlin/rar/kotlin/model/WikiLinksResponse.kt @@ -1,4 +1,4 @@ -package point.rar.model +package rar.kotlin.model import kotlinx.serialization.Serializable diff --git a/wikigame/algo/src/main/java/repository/WikiGameAlgoImpl.kt b/src/main/kotlin/rar/kotlin/repository/WikiGameAlgoImpl.kt similarity index 96% rename from wikigame/algo/src/main/java/repository/WikiGameAlgoImpl.kt rename to src/main/kotlin/rar/kotlin/repository/WikiGameAlgoImpl.kt index 14d351f..73b481c 100644 --- a/wikigame/algo/src/main/java/repository/WikiGameAlgoImpl.kt +++ b/src/main/kotlin/rar/kotlin/repository/WikiGameAlgoImpl.kt @@ -2,11 +2,11 @@ package repository import kotlinx.coroutines.* import kotlinx.coroutines.channels.Channel -import model.BackwardPage -import model.ForwardPage -import point.rar.repository.WikiGame -import point.rar.wikisuspend.WikiRemoteDataSource -import point.rar.wikisuspend.WikiRemoteDataSourceImpl +import rar.kotlin.model.BackwardPage +import rar.kotlin.model.ForwardPage +import rar.java.repository.WikiGame +import rar.kotlin.wiki.WikiRemoteDataSource +import rar.kotlin.wiki.WikiRemoteDataSourceImpl import java.lang.RuntimeException import java.util.* import java.util.concurrent.ConcurrentHashMap diff --git a/wikigame/coroutines/src/main/java/coroutines/repository/WikiGameCoroImpl.kt b/src/main/kotlin/rar/kotlin/repository/WikiGameCoroImpl.kt similarity index 94% rename from wikigame/coroutines/src/main/java/coroutines/repository/WikiGameCoroImpl.kt rename to src/main/kotlin/rar/kotlin/repository/WikiGameCoroImpl.kt index efbe918..a8acdfd 100644 --- a/wikigame/coroutines/src/main/java/coroutines/repository/WikiGameCoroImpl.kt +++ b/src/main/kotlin/rar/kotlin/repository/WikiGameCoroImpl.kt @@ -2,10 +2,10 @@ package coroutines.repository import kotlinx.coroutines.* import kotlinx.coroutines.channels.Channel -import point.rar.wikisuspend.WikiRemoteDataSource -import point.rar.wikisuspend.WikiRemoteDataSourceImpl -import point.rar.model.Page -import point.rar.repository.WikiGame +import rar.kotlin.model.Page +import rar.java.repository.WikiGame +import rar.kotlin.wiki.WikiRemoteDataSource +import rar.kotlin.wiki.WikiRemoteDataSourceImpl import java.lang.RuntimeException import java.util.Optional import java.util.concurrent.ConcurrentHashMap diff --git a/wikigame/src/main/java/point/rar/wikisuspend/WikiRemoteDataSource.kt b/src/main/kotlin/rar/kotlin/wiki/WikiRemoteDataSource.kt similarity index 84% rename from wikigame/src/main/java/point/rar/wikisuspend/WikiRemoteDataSource.kt rename to src/main/kotlin/rar/kotlin/wiki/WikiRemoteDataSource.kt index 0313113..ba90a9a 100644 --- a/wikigame/src/main/java/point/rar/wikisuspend/WikiRemoteDataSource.kt +++ b/src/main/kotlin/rar/kotlin/wiki/WikiRemoteDataSource.kt @@ -1,4 +1,4 @@ -package point.rar.wikisuspend +package rar.kotlin.wiki interface WikiRemoteDataSource { suspend fun getLinksByTitle(title: String): List diff --git a/wikigame/src/main/java/point/rar/wikisuspend/WikiRemoteDataSourceImpl.kt b/src/main/kotlin/rar/kotlin/wiki/WikiRemoteDataSourceImpl.kt similarity index 95% rename from wikigame/src/main/java/point/rar/wikisuspend/WikiRemoteDataSourceImpl.kt rename to src/main/kotlin/rar/kotlin/wiki/WikiRemoteDataSourceImpl.kt index 4fa4065..bdcf86e 100644 --- a/wikigame/src/main/java/point/rar/wikisuspend/WikiRemoteDataSourceImpl.kt +++ b/src/main/kotlin/rar/kotlin/wiki/WikiRemoteDataSourceImpl.kt @@ -1,4 +1,4 @@ -package point.rar.wikisuspend +package rar.kotlin.wiki import io.github.resilience4j.kotlin.ratelimiter.executeSuspendFunction import io.github.resilience4j.ratelimiter.RateLimiterConfig @@ -11,8 +11,8 @@ import io.ktor.client.request.get import io.ktor.client.request.parameter import io.ktor.serialization.kotlinx.json.json import kotlinx.serialization.json.Json -import point.rar.model.WikiBacklinksResponse -import point.rar.model.WikiLinksResponse +import rar.kotlin.model.WikiBacklinksResponse +import rar.kotlin.model.WikiLinksResponse import java.time.Duration class WikiRemoteDataSourceImpl : WikiRemoteDataSource { diff --git a/wikigame/.gitignore b/wikigame/.gitignore deleted file mode 100644 index 12c29f7..0000000 --- a/wikigame/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -build* -build/* -.gradle/* -.idea/* \ No newline at end of file diff --git a/wikigame/algo/src/main/java/Main.kt b/wikigame/algo/src/main/java/Main.kt deleted file mode 100644 index de3d939..0000000 --- a/wikigame/algo/src/main/java/Main.kt +++ /dev/null @@ -1,12 +0,0 @@ -import point.rar.repository.WikiGame -import repository.WikiGameAlgoImpl - -fun main(args: Array) { - val wikiGame: WikiGame = WikiGameAlgoImpl() - - val start = System.nanoTime() - val path = wikiGame.play("Бакуган", "Библия", 6) - val timeSec = (System.nanoTime() - start) / (1_000_000_000f) - println("$timeSec s.") - println(path) -} \ No newline at end of file diff --git a/wikigame/completable-future/build.gradle.kts b/wikigame/completable-future/build.gradle.kts deleted file mode 100644 index c8e56f3..0000000 --- a/wikigame/completable-future/build.gradle.kts +++ /dev/null @@ -1,34 +0,0 @@ -plugins { - id("java") - kotlin("jvm") version "1.9.10" -} - -group = "point.rar" -version = "1.0-SNAPSHOT" - -repositories { - mavenCentral() -} - -dependencies { - implementation(project(mapOf("path" to ":"))) - testImplementation(platform("org.junit:junit-bom:5.9.1")) - testImplementation("org.junit.jupiter:junit-jupiter") - - val kotlinVersion = "1.9.10" - implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion") - implementation("org.jetbrains.kotlin:kotlin-test:$kotlinVersion") - - implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.14.2") - implementation("org.apache.httpcomponents:httpclient:4.5.13") - implementation("io.github.resilience4j:resilience4j-timelimiter:2.1.0") - implementation("io.github.resilience4j:resilience4j-ratelimiter:2.1.0") -} - -tasks.test { - useJUnitPlatform() -} - -tasks.withType { - options.compilerArgs.add("--enable-preview") -} \ No newline at end of file diff --git a/wikigame/completable-future/src/main/java/MainFuture.java b/wikigame/completable-future/src/main/java/MainFuture.java deleted file mode 100644 index 846523d..0000000 --- a/wikigame/completable-future/src/main/java/MainFuture.java +++ /dev/null @@ -1,13 +0,0 @@ -import point.rar.repository.WikiGame; - -public class MainFuture { - public static void main(String[] args) { - long startTime = System.currentTimeMillis(); - WikiGame wikiGame = new WikiGameFutureImpl(); -// var path = wikiGame.play("Алгебра", "Ятаган", 6); - var path = wikiGame.play("Бакуган", "Библия", 6); - System.out.printf(path.toString()); - long endTime = System.currentTimeMillis(); - System.out.println("Total execution time: " + (endTime - startTime) + "ms"); - } -} \ No newline at end of file diff --git a/wikigame/coroutines/build.gradle.kts b/wikigame/coroutines/build.gradle.kts deleted file mode 100644 index 242b64b..0000000 --- a/wikigame/coroutines/build.gradle.kts +++ /dev/null @@ -1,27 +0,0 @@ -plugins { - id("java") - kotlin("jvm") version "1.9.10" -} - -group = "point.rar" -version = "1.0-SNAPSHOT" - -repositories { - mavenCentral() -} - -dependencies { - implementation(project(mapOf("path" to ":"))) - testImplementation(platform("org.junit:junit-bom:5.9.1")) - testImplementation("org.junit.jupiter:junit-jupiter") - implementation(kotlin("stdlib-jdk8")) - - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3") -} - -tasks.test { - useJUnitPlatform() -} -kotlin { - jvmToolchain(19) -} \ No newline at end of file diff --git a/wikigame/executor/build.gradle.kts b/wikigame/executor/build.gradle.kts deleted file mode 100644 index c8e56f3..0000000 --- a/wikigame/executor/build.gradle.kts +++ /dev/null @@ -1,34 +0,0 @@ -plugins { - id("java") - kotlin("jvm") version "1.9.10" -} - -group = "point.rar" -version = "1.0-SNAPSHOT" - -repositories { - mavenCentral() -} - -dependencies { - implementation(project(mapOf("path" to ":"))) - testImplementation(platform("org.junit:junit-bom:5.9.1")) - testImplementation("org.junit.jupiter:junit-jupiter") - - val kotlinVersion = "1.9.10" - implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion") - implementation("org.jetbrains.kotlin:kotlin-test:$kotlinVersion") - - implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.14.2") - implementation("org.apache.httpcomponents:httpclient:4.5.13") - implementation("io.github.resilience4j:resilience4j-timelimiter:2.1.0") - implementation("io.github.resilience4j:resilience4j-ratelimiter:2.1.0") -} - -tasks.test { - useJUnitPlatform() -} - -tasks.withType { - options.compilerArgs.add("--enable-preview") -} \ No newline at end of file diff --git a/wikigame/gradle/wrapper/gradle-wrapper.properties b/wikigame/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 9c9dcd7..0000000 --- a/wikigame/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Sat Sep 02 18:40:37 MSK 2023 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/wikigame/src/main/java/point/rar/Main.java b/wikigame/src/main/java/point/rar/Main.java deleted file mode 100644 index 23ff025..0000000 --- a/wikigame/src/main/java/point/rar/Main.java +++ /dev/null @@ -1,7 +0,0 @@ -package point.rar; - -public class Main { - public static void main(String[] args) { - System.out.println("Hello world!"); - } -} \ No newline at end of file From e9a4cd7cd4d6fad51ba6361a5d6852aafd1e9b40 Mon Sep 17 00:00:00 2001 From: Daniil Lyubaev Date: Fri, 8 Sep 2023 16:47:23 +0300 Subject: [PATCH 38/58] fix --- .../rar/kotlin/repository/WikiGameCoroImpl.kt | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/src/main/kotlin/rar/kotlin/repository/WikiGameCoroImpl.kt b/src/main/kotlin/rar/kotlin/repository/WikiGameCoroImpl.kt index a8acdfd..20ae737 100644 --- a/src/main/kotlin/rar/kotlin/repository/WikiGameCoroImpl.kt +++ b/src/main/kotlin/rar/kotlin/repository/WikiGameCoroImpl.kt @@ -11,15 +11,10 @@ import java.util.Optional import java.util.concurrent.ConcurrentHashMap class WikiGameCoroImpl : WikiGame { - companion object { - private const val REQUEST_SENT = 1 - private const val RESPONSE_RECEIVED = 2 - } - private val wikiRemoteDataSource: WikiRemoteDataSource = WikiRemoteDataSourceImpl() override fun play(startPageTitle: String, endPageTitle: String, maxDepth: Int): List = runBlocking { - val visitedPages: MutableMap = ConcurrentHashMap() + val visitedPages: MutableMap = ConcurrentHashMap() val ctx = newFixedThreadPoolContext(4, "fixed-thread-context") val scope = CoroutineScope(ctx) @@ -41,9 +36,6 @@ class WikiGameCoroImpl : WikiGame { curPg = curPg.parentPage } while (curPg != null) - val pagesWithResponseCount = visitedPages.entries.count { it.value == RESPONSE_RECEIVED } - println("Received responses from $pagesWithResponseCount pages") - return@runBlocking path.reversed() } @@ -52,13 +44,12 @@ class WikiGameCoroImpl : WikiGame { endPageTitle: String, curDepth: Int, maxDepth: Int, - visitedPages: MutableMap, + visitedPages: MutableMap, coroutineScope: CoroutineScope ): Optional { - if (visitedPages.contains(page.title)) { + if (visitedPages.putIfAbsent(page.title, true) != null) { return Optional.empty() } - visitedPages[page.title] = REQUEST_SENT if (page.title == endPageTitle) { return Optional.of(page) @@ -71,8 +62,6 @@ class WikiGameCoroImpl : WikiGame { // println("Started for ${page.title}, depth = $curDepth") val links = wikiRemoteDataSource.getLinksByTitle(page.title) - visitedPages[page.title] = RESPONSE_RECEIVED - val ch = Channel>() links.forEach { From cb4b80bfa5a9c7877b25dd1ae980761ad8951943 Mon Sep 17 00:00:00 2001 From: Daniil Lyubaev Date: Fri, 8 Sep 2023 23:45:05 +0300 Subject: [PATCH 39/58] add loom impl --- .../java/rar/java/repository/LoomImpl.java | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 src/main/java/rar/java/repository/LoomImpl.java diff --git a/src/main/java/rar/java/repository/LoomImpl.java b/src/main/java/rar/java/repository/LoomImpl.java new file mode 100644 index 0000000..ecb78bc --- /dev/null +++ b/src/main/java/rar/java/repository/LoomImpl.java @@ -0,0 +1,99 @@ +package rar.java.repository; + +import rar.java.wiki.WikiRemoteDataSource; +import rar.java.wiki.WikiRemoteDataSourceImpl; +import rar.kotlin.model.Page; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.concurrent.SynchronousQueue; + +public class LoomImpl implements WikiGame { + + private final WikiRemoteDataSource wikiRemoteDataSource = new WikiRemoteDataSourceImpl(); + @Override + public List play(String startPageTitle, String endPageTitle, int maxDepth) { + var visitedPages = new ConcurrentHashMap(); + var executor = Executors.newVirtualThreadPerTaskExecutor(); + + var startPage = new Page(startPageTitle, null); + + var res = processPage(startPage, endPageTitle, 0, maxDepth, visitedPages, executor); + if (res.isEmpty()) { + throw new RuntimeException("Depth reached"); + } + + executor.shutdown(); + + var endPage = res.get(); + var path = new ArrayList(); + + var curPg = endPage; + do { + path.add(curPg.getTitle()); + curPg = curPg.getParentPage(); + } while (curPg != null); + + Collections.reverse(path); + return path; + } + + private Optional processPage( + Page page, + String endPageTitle, + int curDepth, + int maxDepth, + Map visitedPages, + Executor executor + ) { + if (visitedPages.putIfAbsent(page.getTitle(), true) != null) { + return Optional.empty(); + } + + if (page.getTitle().equals(endPageTitle)) { + return Optional.of(page); + } + + if (curDepth == maxDepth) { + return Optional.empty(); + } + + var links = wikiRemoteDataSource.getLinksByTitle(page.getTitle()); + +// System.out.println("got response from " + page.getTitle()); + + var queue = new SynchronousQueue>(); + + links.forEach((link) -> { + executor.execute(() -> { + var res = processPage( + new Page(link, page), + endPageTitle, + curDepth+1, + maxDepth, + visitedPages, + executor + ); + + try { + queue.put(res); + } catch (Throwable e) {} + }); + }); + + for (int i = 0; i < links.size(); i++) { + try { + var res = queue.take(); + if (res.isPresent()) { + return res; + } + } catch (Throwable e) { + return Optional.empty(); + } + } + + return Optional.empty(); + } +} From 68267ac88b577a4a1ed13a02a65591951f56d89e Mon Sep 17 00:00:00 2001 From: Daniil Lyubaev Date: Tue, 19 Sep 2023 14:08:10 +0300 Subject: [PATCH 40/58] algo loom part tbd --- src/main/java/rar/java/Main.java | 4 +- .../rar/java/repository/LoomAlgoImpl.java | 94 +++++++++++++++++++ 2 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 src/main/java/rar/java/repository/LoomAlgoImpl.java diff --git a/src/main/java/rar/java/Main.java b/src/main/java/rar/java/Main.java index 0e54aa6..e744547 100644 --- a/src/main/java/rar/java/Main.java +++ b/src/main/java/rar/java/Main.java @@ -1,13 +1,15 @@ package rar.java; +import rar.java.repository.LoomImpl; import rar.java.repository.WikiGame; import rar.java.repository.WikiGameExecutorImpl; import rar.java.repository.WikiGameFutureImpl; +import repository.WikiGameAlgoImpl; public class Main { public static void main(String[] args) { long startTime = System.currentTimeMillis(); - WikiGame wikiGame = new WikiGameExecutorImpl(); + WikiGame wikiGame = new WikiGameAlgoImpl(); // var path = wikiGame.play("Алгебра", "Ятаган", 6); var path = wikiGame.play("Бакуган", "Библия", 6); System.out.println(path); diff --git a/src/main/java/rar/java/repository/LoomAlgoImpl.java b/src/main/java/rar/java/repository/LoomAlgoImpl.java new file mode 100644 index 0000000..faca8f8 --- /dev/null +++ b/src/main/java/rar/java/repository/LoomAlgoImpl.java @@ -0,0 +1,94 @@ +package rar.java.repository; + +import rar.java.wiki.WikiRemoteDataSource; +import rar.java.wiki.WikiRemoteDataSourceImpl; +import rar.kotlin.model.BackwardPage; +import rar.kotlin.model.ForwardPage; +import rar.kotlin.model.Page; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executors; +import java.util.concurrent.SynchronousQueue; + +public class LoomAlgoImpl implements WikiGame { + + private record PairPages(ForwardPage forwardPage, BackwardPage backwardPage) {} + + private final WikiRemoteDataSource wikiRemoteDataSource = new WikiRemoteDataSourceImpl(); + @Override + public List play(String startPageTitle, String endPageTitle, int maxDepth) { + var visitedForwardPages = new ConcurrentHashMap(); + var visitedBackwardPages = new ConcurrentHashMap(); + + var executor = Executors.newVirtualThreadPerTaskExecutor(); + + var startForwardPage = new ForwardPage(startPageTitle, null); + var endBackwardPage = new BackwardPage(endPageTitle, null); + + var queue = new SynchronousQueue>(); + + executor.execute(() -> { + var res = ; + try { + queue.put(res); + } catch (Throwable e ) {} + }); + + executor.execute(() -> { + try { + queue.put(res); + } catch (Throwable e ) {} + }); + + for (int i = 0; i < 2; i++) { + try { + var res = queue.take(); + if (res.isPresent()) { + var pair = res.get(); + } + } catch (Throwable e) {} + } + + return pathOpt.get(); + } + + private Optional> process( + String startPageTitle, + String endPageTitle, + int maxDepth + ) { + + } + + private List getFinalPathFromForwardAndBackward( + ForwardPage forwardPage, + BackwardPage backwardPage + ) { + var path = new ArrayList(); + + var forwardPages = new ArrayList(); + var curFwdPage = forwardPage; + while (curFwdPage != null) { + forwardPages.add(curFwdPage); + curFwdPage = curFwdPage.getParentPage(); + } + + Collections.reverse(forwardPages); + for (var fwdPg : forwardPages) { + path.add(fwdPg.getTitle()); + } + + var curBwdPage = backwardPage.getChildPage(); + while (curBwdPage != null) { + path.add(curBwdPage.getTitle()); + curBwdPage = curBwdPage.getChildPage(); + } + + return path; + } + +} From cbc80113a819f1afd59ab40d82a1edd6383ecb92 Mon Sep 17 00:00:00 2001 From: Daniil Lyubaev Date: Tue, 19 Sep 2023 15:44:36 +0300 Subject: [PATCH 41/58] Working Loom two-way algo version --- src/main/java/rar/java/Main.java | 7 +- .../rar/java/repository/LoomAlgoImpl.java | 150 ++++++++++++++++-- .../java/wiki/WikiRemoteDataSourceImpl.java | 41 ++++- .../kotlin/rar/kotlin/model/QueryBacklinks.kt | 2 +- .../rar/kotlin/model/WikiBacklinksResponse.kt | 2 +- 5 files changed, 178 insertions(+), 24 deletions(-) diff --git a/src/main/java/rar/java/Main.java b/src/main/java/rar/java/Main.java index e744547..d528655 100644 --- a/src/main/java/rar/java/Main.java +++ b/src/main/java/rar/java/Main.java @@ -1,15 +1,12 @@ package rar.java; -import rar.java.repository.LoomImpl; -import rar.java.repository.WikiGame; -import rar.java.repository.WikiGameExecutorImpl; -import rar.java.repository.WikiGameFutureImpl; +import rar.java.repository.*; import repository.WikiGameAlgoImpl; public class Main { public static void main(String[] args) { long startTime = System.currentTimeMillis(); - WikiGame wikiGame = new WikiGameAlgoImpl(); + WikiGame wikiGame = new LoomAlgoImpl(); // var path = wikiGame.play("Алгебра", "Ятаган", 6); var path = wikiGame.play("Бакуган", "Библия", 6); System.out.println(path); diff --git a/src/main/java/rar/java/repository/LoomAlgoImpl.java b/src/main/java/rar/java/repository/LoomAlgoImpl.java index faca8f8..f080c1f 100644 --- a/src/main/java/rar/java/repository/LoomAlgoImpl.java +++ b/src/main/java/rar/java/repository/LoomAlgoImpl.java @@ -6,13 +6,8 @@ import rar.kotlin.model.ForwardPage; import rar.kotlin.model.Page; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.Executors; -import java.util.concurrent.SynchronousQueue; +import java.util.*; +import java.util.concurrent.*; public class LoomAlgoImpl implements WikiGame { @@ -21,8 +16,21 @@ private record PairPages(ForwardPage forwardPage, BackwardPage backwardPage) {} private final WikiRemoteDataSource wikiRemoteDataSource = new WikiRemoteDataSourceImpl(); @Override public List play(String startPageTitle, String endPageTitle, int maxDepth) { - var visitedForwardPages = new ConcurrentHashMap(); - var visitedBackwardPages = new ConcurrentHashMap(); + var pathOpt = process(startPageTitle, endPageTitle, maxDepth); + if (pathOpt.isEmpty()) { + throw new RuntimeException("Could not find"); + } + + return pathOpt.get(); + } + + private Optional> process( + String startPageTitle, + String endPageTitle, + int maxDepth + ) { + var visitedForwardPages = new ConcurrentHashMap(); + var visitedBackwardPages = new ConcurrentHashMap(); var executor = Executors.newVirtualThreadPerTaskExecutor(); @@ -32,13 +40,28 @@ public List play(String startPageTitle, String endPageTitle, int maxDept var queue = new SynchronousQueue>(); executor.execute(() -> { - var res = ; + var res = processPageForward( + startForwardPage, + 0, + maxDepth, + visitedForwardPages, + visitedBackwardPages, + executor + ); try { queue.put(res); } catch (Throwable e ) {} }); executor.execute(() -> { + var res = processPageBackward( + endBackwardPage, + 0, + maxDepth, + visitedForwardPages, + visitedBackwardPages, + executor + ); try { queue.put(res); } catch (Throwable e ) {} @@ -49,19 +72,116 @@ public List play(String startPageTitle, String endPageTitle, int maxDept var res = queue.take(); if (res.isPresent()) { var pair = res.get(); + return Optional.of(getFinalPathFromForwardAndBackward(pair.forwardPage, pair.backwardPage)); } } catch (Throwable e) {} } - return pathOpt.get(); + return Optional.empty(); } - private Optional> process( - String startPageTitle, - String endPageTitle, - int maxDepth + private Optional processPageForward( + ForwardPage page, + int curDepth, + int maxDepth, + ConcurrentMap visitedForwardPages, + ConcurrentMap visitedBackwardPages, + Executor executor ) { + if (visitedForwardPages.putIfAbsent(page.getTitle(), page) != null) { + return Optional.empty(); + } + + var backwardPage = visitedBackwardPages.get(page.getTitle()); + if (backwardPage != null) { + return Optional.of(new PairPages(page, backwardPage)); + } + + if (curDepth == maxDepth) { + return Optional.empty(); + } + + var links = wikiRemoteDataSource.getLinksByTitle(page.getTitle()); + + var queue = new SynchronousQueue>(); + + links.forEach((String title) -> executor.execute(() -> { + var res = processPageForward( + new ForwardPage(title, page), + curDepth + 1, + maxDepth, + visitedForwardPages, + visitedBackwardPages, + executor + ); + + try { + queue.put(res); + } catch (Throwable e) {} + })); + + for (int i = 0; i < links.size(); i++) { + try { + var res = queue.take(); + if (res.isPresent()) { + return res; + } + } catch(Throwable e) {} + } + + return Optional.empty(); + } + + private Optional processPageBackward( + BackwardPage page, + int curDepth, + int maxDepth, + ConcurrentMap visitedForwardPages, + ConcurrentMap visitedBackwardPages, + Executor executor + ) { + if (visitedBackwardPages.putIfAbsent(page.getTitle(), page) != null) { + return Optional.empty(); + } + + var forwardPage = visitedForwardPages.get(page.getTitle()); + if (forwardPage != null) { + return Optional.of(new PairPages(forwardPage, page)); + } + + if (curDepth == maxDepth) { + return Optional.empty(); + } + + var backlinks = wikiRemoteDataSource.getBacklinksByTitle(page.getTitle()); + + var queue = new SynchronousQueue>(); + + backlinks.forEach((String title) -> executor.execute(() -> { + var res = processPageBackward( + new BackwardPage(title, page), + curDepth + 1, + maxDepth, + visitedForwardPages, + visitedBackwardPages, + executor + ); + + try { + queue.put(res); + } catch (Throwable e) {} + })); + + for (int i = 0; i < backlinks.size(); i++) { + try { + var res = queue.take(); + if (res.isPresent()) { + return res; + } + } catch(Throwable e) {} + } + return Optional.empty(); } private List getFinalPathFromForwardAndBackward( diff --git a/src/main/java/rar/java/wiki/WikiRemoteDataSourceImpl.java b/src/main/java/rar/java/wiki/WikiRemoteDataSourceImpl.java index f6fb0b1..9baca9a 100644 --- a/src/main/java/rar/java/wiki/WikiRemoteDataSourceImpl.java +++ b/src/main/java/rar/java/wiki/WikiRemoteDataSourceImpl.java @@ -8,6 +8,7 @@ import org.apache.http.client.utils.URIBuilder; import org.jetbrains.annotations.NotNull; import rar.kotlin.model.Link; +import rar.kotlin.model.WikiBacklinksResponse; import rar.kotlin.model.WikiLinksResponse; import java.net.URISyntaxException; @@ -45,7 +46,7 @@ public List getLinksByTitle(String title) { ) .body() ).get(); - System.out.println("Got links from: " + title); +// System.out.println("Got links from: " + title); WikiLinksResponse response = objectMapper.readValue(responseBody, WikiLinksResponse.class); return parseResponse(response); @@ -76,6 +77,42 @@ private static List parseResponse(WikiLinksResponse response) { @Override public List getBacklinksByTitle(String title) { - return null; + try { + String responseBody = RateLimiter.decorateCheckedSupplier(rateLimiter, () -> + HttpClient.newBuilder() + .build() + .send( + HttpRequest.newBuilder() + .uri(getBacklinksUriBuilder(title).build()) + .GET() + .build(), + HttpResponse.BodyHandlers.ofString() + ) + .body() + ).get(); +// System.out.println("Got links from: " + title); + WikiBacklinksResponse response = objectMapper.readValue(responseBody, WikiBacklinksResponse.class); + + return parseBacklinksResponse(response); + } catch (Throwable e) { + throw new RuntimeException(e); + } + } + + @NotNull + private static URIBuilder getBacklinksUriBuilder(String title) throws URISyntaxException { + URIBuilder uriBuilder = new URIBuilder(URL); + uriBuilder.addParameter("action", "query"); + uriBuilder.addParameter("bltitle", title); + uriBuilder.addParameter("list", "backlinks"); + uriBuilder.addParameter("bllimit", "max"); + uriBuilder.addParameter("format", "json"); + uriBuilder.addParameter("blnamespace", "0"); + return uriBuilder; + } + + @NotNull + private static List parseBacklinksResponse(WikiBacklinksResponse response) { + return response.getQuery().getBacklinks().stream().map(Link::getTitle).toList(); } } diff --git a/src/main/kotlin/rar/kotlin/model/QueryBacklinks.kt b/src/main/kotlin/rar/kotlin/model/QueryBacklinks.kt index 6a11be0..faa89fc 100644 --- a/src/main/kotlin/rar/kotlin/model/QueryBacklinks.kt +++ b/src/main/kotlin/rar/kotlin/model/QueryBacklinks.kt @@ -4,5 +4,5 @@ import kotlinx.serialization.Serializable @Serializable data class QueryBacklinks( - val backlinks: List, + val backlinks: List = emptyList(), ) diff --git a/src/main/kotlin/rar/kotlin/model/WikiBacklinksResponse.kt b/src/main/kotlin/rar/kotlin/model/WikiBacklinksResponse.kt index 3669b4b..a95bc5d 100644 --- a/src/main/kotlin/rar/kotlin/model/WikiBacklinksResponse.kt +++ b/src/main/kotlin/rar/kotlin/model/WikiBacklinksResponse.kt @@ -4,5 +4,5 @@ import kotlinx.serialization.Serializable @Serializable data class WikiBacklinksResponse( - val query: QueryBacklinks, + val query: QueryBacklinks = QueryBacklinks(emptyList()), ) From 53bf4cc5f95e61c60f5a93918e19fe69b2b580ad Mon Sep 17 00:00:00 2001 From: Daniil Lyubaev Date: Tue, 19 Sep 2023 15:49:58 +0300 Subject: [PATCH 42/58] Comment --- src/main/kotlin/rar/kotlin/repository/WikiGameAlgoImpl.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/kotlin/rar/kotlin/repository/WikiGameAlgoImpl.kt b/src/main/kotlin/rar/kotlin/repository/WikiGameAlgoImpl.kt index 73b481c..863d237 100644 --- a/src/main/kotlin/rar/kotlin/repository/WikiGameAlgoImpl.kt +++ b/src/main/kotlin/rar/kotlin/repository/WikiGameAlgoImpl.kt @@ -11,6 +11,10 @@ import java.lang.RuntimeException import java.util.* import java.util.concurrent.ConcurrentHashMap +/** + * Two-way algo version written in Kotlin. + * Use Loom version instead. + */ class WikiGameAlgoImpl : WikiGame { private val wikiRemoteDataSource: WikiRemoteDataSource = WikiRemoteDataSourceImpl() From 31ac0950714f8b4839a977e8c5d8119fb0db944d Mon Sep 17 00:00:00 2001 From: Daniil Lyubaev Date: Fri, 29 Sep 2023 17:06:10 +0300 Subject: [PATCH 43/58] Some refactoring --- .../java/rar/java/repository/LoomAlgoImpl.java | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/main/java/rar/java/repository/LoomAlgoImpl.java b/src/main/java/rar/java/repository/LoomAlgoImpl.java index f080c1f..dfaae12 100644 --- a/src/main/java/rar/java/repository/LoomAlgoImpl.java +++ b/src/main/java/rar/java/repository/LoomAlgoImpl.java @@ -14,17 +14,9 @@ public class LoomAlgoImpl implements WikiGame { private record PairPages(ForwardPage forwardPage, BackwardPage backwardPage) {} private final WikiRemoteDataSource wikiRemoteDataSource = new WikiRemoteDataSourceImpl(); - @Override - public List play(String startPageTitle, String endPageTitle, int maxDepth) { - var pathOpt = process(startPageTitle, endPageTitle, maxDepth); - if (pathOpt.isEmpty()) { - throw new RuntimeException("Could not find"); - } - - return pathOpt.get(); - } - private Optional> process( + @Override + public List play( String startPageTitle, String endPageTitle, int maxDepth @@ -72,12 +64,12 @@ private Optional> process( var res = queue.take(); if (res.isPresent()) { var pair = res.get(); - return Optional.of(getFinalPathFromForwardAndBackward(pair.forwardPage, pair.backwardPage)); + return getFinalPathFromForwardAndBackward(pair.forwardPage, pair.backwardPage); } } catch (Throwable e) {} } - return Optional.empty(); + throw new RuntimeException("Could not find"); } private Optional processPageForward( From 6cecfff1be411fb361697a4f786e8a29b497de25 Mon Sep 17 00:00:00 2001 From: Daniil Lyubaev Date: Sun, 1 Oct 2023 13:30:49 +0300 Subject: [PATCH 44/58] Structured concurrency --- .../java/rar/java/repository/LoomImpl.java | 76 +++++++------------ 1 file changed, 27 insertions(+), 49 deletions(-) diff --git a/src/main/java/rar/java/repository/LoomImpl.java b/src/main/java/rar/java/repository/LoomImpl.java index ecb78bc..97aafc0 100644 --- a/src/main/java/rar/java/repository/LoomImpl.java +++ b/src/main/java/rar/java/repository/LoomImpl.java @@ -1,14 +1,12 @@ package rar.java.repository; +import jdk.incubator.concurrent.StructuredTaskScope; import rar.java.wiki.WikiRemoteDataSource; import rar.java.wiki.WikiRemoteDataSourceImpl; import rar.kotlin.model.Page; import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; -import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.*; public class LoomImpl implements WikiGame { @@ -16,21 +14,19 @@ public class LoomImpl implements WikiGame { @Override public List play(String startPageTitle, String endPageTitle, int maxDepth) { var visitedPages = new ConcurrentHashMap(); - var executor = Executors.newVirtualThreadPerTaskExecutor(); var startPage = new Page(startPageTitle, null); - var res = processPage(startPage, endPageTitle, 0, maxDepth, visitedPages, executor); - if (res.isEmpty()) { - throw new RuntimeException("Depth reached"); + Page resultPage; + try { + resultPage = processPage(startPage, endPageTitle, 0, maxDepth, visitedPages); + } catch (Throwable e) { + throw new RuntimeException(e); } - executor.shutdown(); - - var endPage = res.get(); var path = new ArrayList(); - var curPg = endPage; + var curPg = resultPage; do { path.add(curPg.getTitle()); curPg = curPg.getParentPage(); @@ -40,60 +36,42 @@ public List play(String startPageTitle, String endPageTitle, int maxDept return path; } - private Optional processPage( - Page page, - String endPageTitle, - int curDepth, - int maxDepth, - Map visitedPages, - Executor executor - ) { + private Page processPage( + Page page, + String endPageTitle, + int curDepth, + int maxDepth, + Map visitedPages + ) throws InterruptedException, ExecutionException { if (visitedPages.putIfAbsent(page.getTitle(), true) != null) { - return Optional.empty(); + throw new RuntimeException("Already visited"); } if (page.getTitle().equals(endPageTitle)) { - return Optional.of(page); + return page; } if (curDepth == maxDepth) { - return Optional.empty(); + throw new RuntimeException("Depth reached"); } var links = wikiRemoteDataSource.getLinksByTitle(page.getTitle()); -// System.out.println("got response from " + page.getTitle()); - - var queue = new SynchronousQueue>(); - - links.forEach((link) -> { - executor.execute(() -> { - var res = processPage( + try(var scope = new StructuredTaskScope.ShutdownOnSuccess()) { + links.forEach((link) -> { + scope.fork(() -> processPage( new Page(link, page), endPageTitle, curDepth+1, maxDepth, - visitedPages, - executor + visitedPages + ) ); - - try { - queue.put(res); - } catch (Throwable e) {} }); - }); - - for (int i = 0; i < links.size(); i++) { - try { - var res = queue.take(); - if (res.isPresent()) { - return res; - } - } catch (Throwable e) { - return Optional.empty(); - } - } - return Optional.empty(); + scope.join(); + + return scope.result(); + } } } From 4005764036767fc74b900cfe88df75e1a8c223a9 Mon Sep 17 00:00:00 2001 From: Daniil Lyubaev Date: Sun, 1 Oct 2023 13:31:19 +0300 Subject: [PATCH 45/58] Incubator module --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 963efaf..b8acd29 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -50,7 +50,7 @@ tasks.test { useJUnitPlatform() } tasks.withType { - options.compilerArgs.add("--enable-preview") + options.compilerArgs.addAll(listOf("--enable-preview", "--add-modules", "jdk.incubator.concurrent")) } kotlin { jvmToolchain(19) From ac04958e6799658ba9c318d5588786208316be80 Mon Sep 17 00:00:00 2001 From: Daniil Lyubaev Date: Sun, 1 Oct 2023 13:41:47 +0300 Subject: [PATCH 46/58] Structured concurrency for LoomAlgoImpl + refactor --- .../rar/java/repository/LoomAlgoImpl.java | 192 +++++++----------- .../java/rar/java/repository/LoomImpl.java | 16 +- 2 files changed, 86 insertions(+), 122 deletions(-) diff --git a/src/main/java/rar/java/repository/LoomAlgoImpl.java b/src/main/java/rar/java/repository/LoomAlgoImpl.java index dfaae12..55d9292 100644 --- a/src/main/java/rar/java/repository/LoomAlgoImpl.java +++ b/src/main/java/rar/java/repository/LoomAlgoImpl.java @@ -1,184 +1,150 @@ package rar.java.repository; +import jdk.incubator.concurrent.StructuredTaskScope; import rar.java.wiki.WikiRemoteDataSource; import rar.java.wiki.WikiRemoteDataSourceImpl; import rar.kotlin.model.BackwardPage; import rar.kotlin.model.ForwardPage; import rar.kotlin.model.Page; +import java.awt.print.PageFormat; import java.util.*; import java.util.concurrent.*; public class LoomAlgoImpl implements WikiGame { - private record PairPages(ForwardPage forwardPage, BackwardPage backwardPage) {} + private record PairPages(ForwardPage forwardPage, BackwardPage backwardPage) { + } private final WikiRemoteDataSource wikiRemoteDataSource = new WikiRemoteDataSourceImpl(); @Override public List play( - String startPageTitle, - String endPageTitle, - int maxDepth + String startPageTitle, + String endPageTitle, + int maxDepth ) { var visitedForwardPages = new ConcurrentHashMap(); var visitedBackwardPages = new ConcurrentHashMap(); - var executor = Executors.newVirtualThreadPerTaskExecutor(); - var startForwardPage = new ForwardPage(startPageTitle, null); var endBackwardPage = new BackwardPage(endPageTitle, null); - var queue = new SynchronousQueue>(); - - executor.execute(() -> { - var res = processPageForward( - startForwardPage, - 0, - maxDepth, - visitedForwardPages, - visitedBackwardPages, - executor - ); - try { - queue.put(res); - } catch (Throwable e ) {} - }); - - executor.execute(() -> { - var res = processPageBackward( + try (var scope = new StructuredTaskScope.ShutdownOnSuccess()) { + scope.fork(() -> processPageForward( + startForwardPage, + 0, + maxDepth, + visitedForwardPages, + visitedBackwardPages + )); + + scope.fork(() -> { + return processPageBackward( endBackwardPage, 0, maxDepth, visitedForwardPages, - visitedBackwardPages, - executor - ); - try { - queue.put(res); - } catch (Throwable e ) {} - }); - - for (int i = 0; i < 2; i++) { - try { - var res = queue.take(); - if (res.isPresent()) { - var pair = res.get(); - return getFinalPathFromForwardAndBackward(pair.forwardPage, pair.backwardPage); - } - } catch (Throwable e) {} - } + visitedBackwardPages + ); + }); + + scope.join(); - throw new RuntimeException("Could not find"); + var pairPagesResult = scope.result(); + + return getFinalPathFromForwardAndBackward(pairPagesResult.forwardPage, pairPagesResult.backwardPage); + } catch (Throwable e) { + throw new RuntimeException(e); + } } - private Optional processPageForward( - ForwardPage page, - int curDepth, - int maxDepth, - ConcurrentMap visitedForwardPages, - ConcurrentMap visitedBackwardPages, - Executor executor + private PairPages processPageForward( + ForwardPage page, + int curDepth, + int maxDepth, + ConcurrentMap visitedForwardPages, + ConcurrentMap visitedBackwardPages ) { if (visitedForwardPages.putIfAbsent(page.getTitle(), page) != null) { - return Optional.empty(); + throw new RuntimeException("Already visited"); } var backwardPage = visitedBackwardPages.get(page.getTitle()); if (backwardPage != null) { - return Optional.of(new PairPages(page, backwardPage)); + return new PairPages(page, backwardPage); } if (curDepth == maxDepth) { - return Optional.empty(); + throw new RuntimeException("Depth reached"); } var links = wikiRemoteDataSource.getLinksByTitle(page.getTitle()); - var queue = new SynchronousQueue>(); - - links.forEach((String title) -> executor.execute(() -> { - var res = processPageForward( - new ForwardPage(title, page), - curDepth + 1, - maxDepth, - visitedForwardPages, - visitedBackwardPages, - executor - ); - - try { - queue.put(res); - } catch (Throwable e) {} - })); - - for (int i = 0; i < links.size(); i++) { - try { - var res = queue.take(); - if (res.isPresent()) { - return res; - } - } catch(Throwable e) {} + try (var scope = new StructuredTaskScope.ShutdownOnSuccess()) { + links.forEach((link) -> { + scope.fork(() -> processPageForward( + new ForwardPage(link, page), + curDepth + 1, + maxDepth, + visitedForwardPages, + visitedBackwardPages + ) + ); + }); + + scope.join(); + + return scope.result(); + } catch (Throwable e) { + throw new RuntimeException(e); } - - return Optional.empty(); } - private Optional processPageBackward( - BackwardPage page, - int curDepth, - int maxDepth, - ConcurrentMap visitedForwardPages, - ConcurrentMap visitedBackwardPages, - Executor executor + private PairPages processPageBackward( + BackwardPage page, + int curDepth, + int maxDepth, + ConcurrentMap visitedForwardPages, + ConcurrentMap visitedBackwardPages ) { if (visitedBackwardPages.putIfAbsent(page.getTitle(), page) != null) { - return Optional.empty(); + throw new RuntimeException("Already visited"); } var forwardPage = visitedForwardPages.get(page.getTitle()); if (forwardPage != null) { - return Optional.of(new PairPages(forwardPage, page)); + return new PairPages(forwardPage, page); } if (curDepth == maxDepth) { - return Optional.empty(); + throw new RuntimeException("Depth reached"); } var backlinks = wikiRemoteDataSource.getBacklinksByTitle(page.getTitle()); - var queue = new SynchronousQueue>(); - - backlinks.forEach((String title) -> executor.execute(() -> { - var res = processPageBackward( - new BackwardPage(title, page), + try (var scope = new StructuredTaskScope.ShutdownOnSuccess()) { + backlinks.forEach((link) -> { + scope.fork(() -> processPageBackward( + new BackwardPage(link, page), curDepth + 1, maxDepth, visitedForwardPages, - visitedBackwardPages, - executor - ); - - try { - queue.put(res); - } catch (Throwable e) {} - })); - - for (int i = 0; i < backlinks.size(); i++) { - try { - var res = queue.take(); - if (res.isPresent()) { - return res; - } - } catch(Throwable e) {} - } + visitedBackwardPages + )); + }); - return Optional.empty(); + scope.join(); + + return scope.result(); + } catch (Throwable e) { + throw new RuntimeException(e); + } } private List getFinalPathFromForwardAndBackward( - ForwardPage forwardPage, - BackwardPage backwardPage + ForwardPage forwardPage, + BackwardPage backwardPage ) { var path = new ArrayList(); diff --git a/src/main/java/rar/java/repository/LoomImpl.java b/src/main/java/rar/java/repository/LoomImpl.java index 97aafc0..7cf48e9 100644 --- a/src/main/java/rar/java/repository/LoomImpl.java +++ b/src/main/java/rar/java/repository/LoomImpl.java @@ -11,18 +11,14 @@ public class LoomImpl implements WikiGame { private final WikiRemoteDataSource wikiRemoteDataSource = new WikiRemoteDataSourceImpl(); + @Override public List play(String startPageTitle, String endPageTitle, int maxDepth) { var visitedPages = new ConcurrentHashMap(); var startPage = new Page(startPageTitle, null); - Page resultPage; - try { - resultPage = processPage(startPage, endPageTitle, 0, maxDepth, visitedPages); - } catch (Throwable e) { - throw new RuntimeException(e); - } + Page resultPage = processPage(startPage, endPageTitle, 0, maxDepth, visitedPages); var path = new ArrayList(); @@ -42,7 +38,7 @@ private Page processPage( int curDepth, int maxDepth, Map visitedPages - ) throws InterruptedException, ExecutionException { + ) { if (visitedPages.putIfAbsent(page.getTitle(), true) != null) { throw new RuntimeException("Already visited"); } @@ -57,12 +53,12 @@ private Page processPage( var links = wikiRemoteDataSource.getLinksByTitle(page.getTitle()); - try(var scope = new StructuredTaskScope.ShutdownOnSuccess()) { + try (var scope = new StructuredTaskScope.ShutdownOnSuccess()) { links.forEach((link) -> { scope.fork(() -> processPage( new Page(link, page), endPageTitle, - curDepth+1, + curDepth + 1, maxDepth, visitedPages ) @@ -72,6 +68,8 @@ private Page processPage( scope.join(); return scope.result(); + } catch (Throwable e) { + throw new RuntimeException(e); } } } From 03ffb8f55b341b07e39c03ac391615b8f0961af2 Mon Sep 17 00:00:00 2001 From: Daniil Lyubaev Date: Sun, 1 Oct 2023 15:35:20 +0300 Subject: [PATCH 47/58] Refactor --- build.gradle.kts | 1 + .../rar/java/repository/LoomAlgoImpl.java | 16 +- src/main/kotlin/rar/kotlin/Main.kt | 16 -- .../rar/kotlin/repository/WikiGameAlgoImpl.kt | 214 ------------------ .../rar/kotlin/repository/WikiGameCoroImpl.kt | 52 ++--- .../kotlin/wiki/WikiRemoteDataSourceImpl.kt | 4 +- 6 files changed, 27 insertions(+), 276 deletions(-) delete mode 100644 src/main/kotlin/rar/kotlin/Main.kt delete mode 100644 src/main/kotlin/rar/kotlin/repository/WikiGameAlgoImpl.kt diff --git a/build.gradle.kts b/build.gradle.kts index b8acd29..1441902 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -17,6 +17,7 @@ dependencies { implementation(kotlin("stdlib-jdk8")) implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-jdk9:1.7.3") val kotlinx_serialization_json_version = "1.4.1" implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinx_serialization_json_version") diff --git a/src/main/java/rar/java/repository/LoomAlgoImpl.java b/src/main/java/rar/java/repository/LoomAlgoImpl.java index 55d9292..4b18f3c 100644 --- a/src/main/java/rar/java/repository/LoomAlgoImpl.java +++ b/src/main/java/rar/java/repository/LoomAlgoImpl.java @@ -39,15 +39,13 @@ public List play( visitedBackwardPages )); - scope.fork(() -> { - return processPageBackward( - endBackwardPage, - 0, - maxDepth, - visitedForwardPages, - visitedBackwardPages - ); - }); + scope.fork(() -> processPageBackward( + endBackwardPage, + 0, + maxDepth, + visitedForwardPages, + visitedBackwardPages + )); scope.join(); diff --git a/src/main/kotlin/rar/kotlin/Main.kt b/src/main/kotlin/rar/kotlin/Main.kt deleted file mode 100644 index 6684ce2..0000000 --- a/src/main/kotlin/rar/kotlin/Main.kt +++ /dev/null @@ -1,16 +0,0 @@ -package rar.kotlin - -import coroutines.repository.WikiGameCoroImpl -import rar.java.repository.WikiGame -import repository.WikiGameAlgoImpl - -fun main(args: Array) { - val wikiGame: WikiGame = WikiGameCoroImpl() - - val start = System.nanoTime() - val path = wikiGame.play("Бакуган", "Библия", 6) - val timeSec = (System.nanoTime() - start) / (1_000_000_000f) - println("$timeSec s.") - println(path) -} - diff --git a/src/main/kotlin/rar/kotlin/repository/WikiGameAlgoImpl.kt b/src/main/kotlin/rar/kotlin/repository/WikiGameAlgoImpl.kt deleted file mode 100644 index 863d237..0000000 --- a/src/main/kotlin/rar/kotlin/repository/WikiGameAlgoImpl.kt +++ /dev/null @@ -1,214 +0,0 @@ -package repository - -import kotlinx.coroutines.* -import kotlinx.coroutines.channels.Channel -import rar.kotlin.model.BackwardPage -import rar.kotlin.model.ForwardPage -import rar.java.repository.WikiGame -import rar.kotlin.wiki.WikiRemoteDataSource -import rar.kotlin.wiki.WikiRemoteDataSourceImpl -import java.lang.RuntimeException -import java.util.* -import java.util.concurrent.ConcurrentHashMap - -/** - * Two-way algo version written in Kotlin. - * Use Loom version instead. - */ -class WikiGameAlgoImpl : WikiGame { - - private val wikiRemoteDataSource: WikiRemoteDataSource = WikiRemoteDataSourceImpl() - override fun play(startPageTitle: String, endPageTitle: String, maxDepth: Int): List { - val pathOpt = process(startPageTitle, endPageTitle, maxDepth) - if (pathOpt.isEmpty) { - throw RuntimeException("Could not find") - } - -// val pagesWithResponseCount = visitedPages.entries.count { it.value == RESPONSE_RECEIVED } -// println("Received responses from $pagesWithResponseCount pages") - - return pathOpt.get() - } - - private fun process( - startPageTitle: String, - endPageTitle: String, - maxDepth: Int, - ): Optional> = runBlocking { - val visitedForwardPages: MutableMap = ConcurrentHashMap() - val visitedBackwardPages: MutableMap = ConcurrentHashMap() - val ctx = newFixedThreadPoolContext(4, "fixed-thread-context") - val scope = CoroutineScope(ctx) - - val startForwardPage = ForwardPage(startPageTitle, null) - val endBackwardPage = BackwardPage(endPageTitle, null) - - val ch = Channel>>() - - scope.launch { - val res = processPageForward( - startForwardPage, - endPageTitle, - 0, - maxDepth, - visitedForwardPages, - visitedBackwardPages, - scope - ) - ch.send(res) - } - scope.launch { - val res = processPageBackward( - endBackwardPage, - endPageTitle, - 0, - maxDepth, - visitedForwardPages, - visitedBackwardPages, - scope - ) - ch.send(res) - } - - for (i in 1..2) { - val res = ch.receive() - if (res.isPresent) { - val pair = res.get() - return@runBlocking Optional.of(getFinalPathFromForwardAndBackward(pair.first, pair.second)) - } - } - - return@runBlocking Optional.empty() - } - - private suspend fun processPageForward( - page: ForwardPage, - endPageTitle: String, - curDepth: Int, - maxDepth: Int, - visitedForwardPages: MutableMap, - visitedBackwardPages: MutableMap, - coroutineScope: CoroutineScope - ): Optional> { - if (visitedForwardPages.putIfAbsent(page.title, page) != null) { - return Optional.empty() - } - - val backwardPage = visitedBackwardPages[page.title] - if (backwardPage != null) { - return Optional.of(Pair(page, backwardPage)) - } - - if (curDepth == maxDepth) { - return Optional.empty() - } - -// println("Started for ${page.title}, depth = $curDepth") - val links = wikiRemoteDataSource.getLinksByTitle(page.title) - - val ch = Channel>>() - - links.forEach { - // Creates new scope because we don't want to wait for all the coroutines to complete - coroutineScope.launch { - val coroRes = processPageForward( - ForwardPage(it, page), - endPageTitle, - curDepth + 1, - maxDepth, - visitedForwardPages, - visitedBackwardPages, - coroutineScope - ) - - ch.send(coroRes) - } - } - - for (i in 1..links.size) { - val chRes = ch.receive() - if (chRes.isPresent) { - return chRes - } - } - - return Optional.empty() - } - - private suspend fun processPageBackward( - page: BackwardPage, - endPageTitle: String, - curDepth: Int, - maxDepth: Int, - visitedForwardPages: MutableMap, - visitedBackwardPages: MutableMap, - coroutineScope: CoroutineScope - ): Optional> { - if (visitedBackwardPages.putIfAbsent(page.title, page) != null) { - return Optional.empty() - } - - val forwardPage = visitedForwardPages[page.title] - if (forwardPage != null) { - return Optional.of(Pair(forwardPage, page)) - } - - if (curDepth == maxDepth) { - return Optional.empty() - } - -// println("Started for ${page.title}, depth = $curDepth") - val backlinks = wikiRemoteDataSource.getBacklinksByTitle(page.title) - - val ch = Channel>>() - - backlinks.forEach { - // Creates new scope because we don't want to wait for all the coroutines to complete - coroutineScope.launch { - val coroRes = processPageBackward( - BackwardPage(it, page), - endPageTitle, - curDepth + 1, - maxDepth, - visitedForwardPages, - visitedBackwardPages, - coroutineScope - ) - - ch.send(coroRes) - } - } - - for (i in 1..backlinks.size) { - val chRes = ch.receive() - if (chRes.isPresent) { - return chRes - } - } - - return Optional.empty() - } - - private fun getFinalPathFromForwardAndBackward(forwardPage: ForwardPage, backwardPage: BackwardPage): List { - val path = mutableListOf() - - val forwardPages = mutableListOf() - var curFwdPage: ForwardPage? = forwardPage - while (curFwdPage != null) { - forwardPages.add(curFwdPage) - curFwdPage = curFwdPage.parentPage - } - - for (fwdPg in forwardPages.reversed()) { - path.add(fwdPg.title) - } - - var curBwdPage: BackwardPage? = backwardPage.childPage - while (curBwdPage != null) { - path.add(curBwdPage.title) - curBwdPage = curBwdPage.childPage - } - - return path - } -} \ No newline at end of file diff --git a/src/main/kotlin/rar/kotlin/repository/WikiGameCoroImpl.kt b/src/main/kotlin/rar/kotlin/repository/WikiGameCoroImpl.kt index 20ae737..930a6e3 100644 --- a/src/main/kotlin/rar/kotlin/repository/WikiGameCoroImpl.kt +++ b/src/main/kotlin/rar/kotlin/repository/WikiGameCoroImpl.kt @@ -1,4 +1,4 @@ -package coroutines.repository +package rar.kotlin.repository import kotlinx.coroutines.* import kotlinx.coroutines.channels.Channel @@ -6,8 +6,6 @@ import rar.kotlin.model.Page import rar.java.repository.WikiGame import rar.kotlin.wiki.WikiRemoteDataSource import rar.kotlin.wiki.WikiRemoteDataSourceImpl -import java.lang.RuntimeException -import java.util.Optional import java.util.concurrent.ConcurrentHashMap class WikiGameCoroImpl : WikiGame { @@ -15,22 +13,14 @@ class WikiGameCoroImpl : WikiGame { override fun play(startPageTitle: String, endPageTitle: String, maxDepth: Int): List = runBlocking { val visitedPages: MutableMap = ConcurrentHashMap() - val ctx = newFixedThreadPoolContext(4, "fixed-thread-context") - val scope = CoroutineScope(ctx) val startPage = Page(startPageTitle, null) - val res = processPage(startPage, endPageTitle, 0, maxDepth, visitedPages, scope) - if (res.isEmpty) { - throw RuntimeException("Depth reached") - } + val resultPage = processPage(startPage, endPageTitle, 0, maxDepth, visitedPages) - ctx.cancelChildren() - - val endPage = res.get() val path = mutableListOf() - var curPg: Page? = endPage + var curPg: Page? = resultPage do { path.add(curPg!!.title) curPg = curPg.parentPage @@ -45,48 +35,42 @@ class WikiGameCoroImpl : WikiGame { curDepth: Int, maxDepth: Int, visitedPages: MutableMap, - coroutineScope: CoroutineScope - ): Optional { + ): Page { if (visitedPages.putIfAbsent(page.title, true) != null) { - return Optional.empty() + throw RuntimeException("Already visited") } if (page.title == endPageTitle) { - return Optional.of(page) + return page } if (curDepth == maxDepth) { - return Optional.empty() + throw RuntimeException("Depth reached") } -// println("Started for ${page.title}, depth = $curDepth") val links = wikiRemoteDataSource.getLinksByTitle(page.title) - val ch = Channel>() + val pageChannel = Channel() - links.forEach { - // Creates new scope because we don't want to wait for all the coroutines to complete - coroutineScope.launch { - val coroRes = processPage( - Page(it, page), + val scope = CoroutineScope(SupervisorJob() + CoroutineExceptionHandler { _, _ -> }) + links.forEach { link -> + scope.launch { + val pageResult = processPage( + Page(link, page), endPageTitle, curDepth + 1, maxDepth, visitedPages, - coroutineScope ) - ch.send(coroRes) + pageChannel.send(pageResult) } } - for (i in 1..links.size) { - val chRes = ch.receive() - if (chRes.isPresent) { - return chRes - } - } + val resultPage = pageChannel.receive() + + scope.cancel() - return Optional.empty() + return resultPage } } \ No newline at end of file diff --git a/src/main/kotlin/rar/kotlin/wiki/WikiRemoteDataSourceImpl.kt b/src/main/kotlin/rar/kotlin/wiki/WikiRemoteDataSourceImpl.kt index bdcf86e..35324f4 100644 --- a/src/main/kotlin/rar/kotlin/wiki/WikiRemoteDataSourceImpl.kt +++ b/src/main/kotlin/rar/kotlin/wiki/WikiRemoteDataSourceImpl.kt @@ -17,7 +17,7 @@ import java.time.Duration class WikiRemoteDataSourceImpl : WikiRemoteDataSource { companion object Parameter { - val URL = "https://ru.wikipedia.org/w/api.php" + const val URL = "https://ru.wikipedia.org/w/api.php" } private val rateLimiterConfig = RateLimiterConfig @@ -51,8 +51,6 @@ class WikiRemoteDataSourceImpl : WikiRemoteDataSource { } } - println("got response from $title") - val wikiLinksResponse: WikiLinksResponse = response.body() val links = wikiLinksResponse From be0f61018cdba4f1b6e0c529072d8fab431ce351 Mon Sep 17 00:00:00 2001 From: Daniil Lyubaev Date: Sun, 1 Oct 2023 21:59:56 +0300 Subject: [PATCH 48/58] Interfaces --- src/main/java/rar/java/Main.java | 16 +++++- .../rar/java/repository/LoomAlgoImpl.java | 17 +++--- .../java/rar/java/repository/LoomImpl.java | 11 ++-- .../java/repository/WikiGameExecutorImpl.java | 4 +- .../java/repository/WikiGameFutureImpl.java | 4 +- .../java/repository/WikiGameSerialImpl.java | 4 +- .../data/repository/WikiRepositoryImpl.java | 26 +++++++++ .../source}/WikiRemoteDataSource.java | 2 +- .../domain/repository/WikiRepository.java | 8 +++ .../WikiRemoteDataSourceImpl.java | 57 +++++++++---------- 10 files changed, 98 insertions(+), 51 deletions(-) create mode 100644 src/main/java/rar/java/wiki/data/repository/WikiRepositoryImpl.java rename src/main/java/rar/java/wiki/{ => data/source}/WikiRemoteDataSource.java (82%) create mode 100644 src/main/java/rar/java/wiki/domain/repository/WikiRepository.java rename src/main/java/rar/java/wiki/{ => remote}/WikiRemoteDataSourceImpl.java (72%) diff --git a/src/main/java/rar/java/Main.java b/src/main/java/rar/java/Main.java index d528655..361bf95 100644 --- a/src/main/java/rar/java/Main.java +++ b/src/main/java/rar/java/Main.java @@ -1,16 +1,26 @@ package rar.java; +import rar.java.wiki.data.repository.WikiRepositoryImpl; +import rar.java.wiki.data.source.WikiRemoteDataSource; +import rar.java.wiki.domain.repository.WikiRepository; +import rar.java.wiki.remote.WikiRemoteDataSourceImpl; import rar.java.repository.*; -import repository.WikiGameAlgoImpl; public class Main { public static void main(String[] args) { + WikiRemoteDataSource wikiRemoteDataSource = new WikiRemoteDataSourceImpl(); + WikiRepository wikiRepository = new WikiRepositoryImpl(wikiRemoteDataSource); + long startTime = System.currentTimeMillis(); - WikiGame wikiGame = new LoomAlgoImpl(); + + WikiGame wikiGame = new LoomImpl(wikiRepository); // var path = wikiGame.play("Алгебра", "Ятаган", 6); +// var path = wikiGame.play("!!!", "Теория гомологий", 6); var path = wikiGame.play("Бакуган", "Библия", 6); - System.out.println(path); + long endTime = System.currentTimeMillis(); + + System.out.println(path); System.out.println("Total execution time: " + (endTime - startTime) + "ms"); } } \ No newline at end of file diff --git a/src/main/java/rar/java/repository/LoomAlgoImpl.java b/src/main/java/rar/java/repository/LoomAlgoImpl.java index 4b18f3c..381d1c5 100644 --- a/src/main/java/rar/java/repository/LoomAlgoImpl.java +++ b/src/main/java/rar/java/repository/LoomAlgoImpl.java @@ -1,13 +1,12 @@ package rar.java.repository; import jdk.incubator.concurrent.StructuredTaskScope; -import rar.java.wiki.WikiRemoteDataSource; -import rar.java.wiki.WikiRemoteDataSourceImpl; +import rar.java.wiki.data.source.WikiRemoteDataSource; +import rar.java.wiki.domain.repository.WikiRepository; +import rar.java.wiki.remote.WikiRemoteDataSourceImpl; import rar.kotlin.model.BackwardPage; import rar.kotlin.model.ForwardPage; -import rar.kotlin.model.Page; -import java.awt.print.PageFormat; import java.util.*; import java.util.concurrent.*; @@ -16,7 +15,11 @@ public class LoomAlgoImpl implements WikiGame { private record PairPages(ForwardPage forwardPage, BackwardPage backwardPage) { } - private final WikiRemoteDataSource wikiRemoteDataSource = new WikiRemoteDataSourceImpl(); + private final WikiRepository wikiRepository; + + public LoomAlgoImpl(WikiRepository wikiRepository) { + this.wikiRepository = wikiRepository; + } @Override public List play( @@ -77,7 +80,7 @@ private PairPages processPageForward( throw new RuntimeException("Depth reached"); } - var links = wikiRemoteDataSource.getLinksByTitle(page.getTitle()); + var links = wikiRepository.getLinksByTitle(page.getTitle()); try (var scope = new StructuredTaskScope.ShutdownOnSuccess()) { links.forEach((link) -> { @@ -119,7 +122,7 @@ private PairPages processPageBackward( throw new RuntimeException("Depth reached"); } - var backlinks = wikiRemoteDataSource.getBacklinksByTitle(page.getTitle()); + var backlinks = wikiRepository.getBacklinksByTitle(page.getTitle()); try (var scope = new StructuredTaskScope.ShutdownOnSuccess()) { backlinks.forEach((link) -> { diff --git a/src/main/java/rar/java/repository/LoomImpl.java b/src/main/java/rar/java/repository/LoomImpl.java index 7cf48e9..d8ddd4e 100644 --- a/src/main/java/rar/java/repository/LoomImpl.java +++ b/src/main/java/rar/java/repository/LoomImpl.java @@ -1,8 +1,7 @@ package rar.java.repository; import jdk.incubator.concurrent.StructuredTaskScope; -import rar.java.wiki.WikiRemoteDataSource; -import rar.java.wiki.WikiRemoteDataSourceImpl; +import rar.java.wiki.domain.repository.WikiRepository; import rar.kotlin.model.Page; import java.util.*; @@ -10,7 +9,11 @@ public class LoomImpl implements WikiGame { - private final WikiRemoteDataSource wikiRemoteDataSource = new WikiRemoteDataSourceImpl(); + private final WikiRepository wikiRepository; + + public LoomImpl(WikiRepository wikiRepository) { + this.wikiRepository = wikiRepository; + } @Override public List play(String startPageTitle, String endPageTitle, int maxDepth) { @@ -51,7 +54,7 @@ private Page processPage( throw new RuntimeException("Depth reached"); } - var links = wikiRemoteDataSource.getLinksByTitle(page.getTitle()); + var links = wikiRepository.getLinksByTitle(page.getTitle()); try (var scope = new StructuredTaskScope.ShutdownOnSuccess()) { links.forEach((link) -> { diff --git a/src/main/java/rar/java/repository/WikiGameExecutorImpl.java b/src/main/java/rar/java/repository/WikiGameExecutorImpl.java index a623125..2cfb412 100644 --- a/src/main/java/rar/java/repository/WikiGameExecutorImpl.java +++ b/src/main/java/rar/java/repository/WikiGameExecutorImpl.java @@ -1,8 +1,8 @@ package rar.java.repository; import org.jetbrains.annotations.NotNull; -import rar.java.wiki.WikiRemoteDataSource; -import rar.java.wiki.WikiRemoteDataSourceImpl; +import rar.java.wiki.data.source.WikiRemoteDataSource; +import rar.java.wiki.remote.WikiRemoteDataSourceImpl; import rar.kotlin.model.Page; import java.util.*; diff --git a/src/main/java/rar/java/repository/WikiGameFutureImpl.java b/src/main/java/rar/java/repository/WikiGameFutureImpl.java index 90c69d2..0c4a48f 100644 --- a/src/main/java/rar/java/repository/WikiGameFutureImpl.java +++ b/src/main/java/rar/java/repository/WikiGameFutureImpl.java @@ -3,8 +3,8 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import org.jetbrains.annotations.NotNull; -import rar.java.wiki.WikiRemoteDataSource; -import rar.java.wiki.WikiRemoteDataSourceImpl; +import rar.java.wiki.data.source.WikiRemoteDataSource; +import rar.java.wiki.remote.WikiRemoteDataSourceImpl; import rar.kotlin.model.Page; import java.util.*; diff --git a/src/main/java/rar/java/repository/WikiGameSerialImpl.java b/src/main/java/rar/java/repository/WikiGameSerialImpl.java index 299d8b4..1ca7414 100644 --- a/src/main/java/rar/java/repository/WikiGameSerialImpl.java +++ b/src/main/java/rar/java/repository/WikiGameSerialImpl.java @@ -1,8 +1,8 @@ package rar.java.repository; import org.jetbrains.annotations.NotNull; -import rar.java.wiki.WikiRemoteDataSource; -import rar.java.wiki.WikiRemoteDataSourceImpl; +import rar.java.wiki.data.source.WikiRemoteDataSource; +import rar.java.wiki.remote.WikiRemoteDataSourceImpl; import rar.kotlin.model.Page; import java.util.*; diff --git a/src/main/java/rar/java/wiki/data/repository/WikiRepositoryImpl.java b/src/main/java/rar/java/wiki/data/repository/WikiRepositoryImpl.java new file mode 100644 index 0000000..6bcf265 --- /dev/null +++ b/src/main/java/rar/java/wiki/data/repository/WikiRepositoryImpl.java @@ -0,0 +1,26 @@ +package rar.java.wiki.data.repository; + +import rar.java.wiki.data.source.WikiRemoteDataSource; +import rar.java.wiki.domain.repository.WikiRepository; + +import java.util.List; + +public class WikiRepositoryImpl implements WikiRepository { + + private final WikiRemoteDataSource wikiRemoteDataSource; + + public WikiRepositoryImpl(WikiRemoteDataSource wikiRemoteDataSource) { + this.wikiRemoteDataSource = wikiRemoteDataSource; + } + + + @Override + public List getLinksByTitle(String title) { + return wikiRemoteDataSource.getLinksByTitle(title); + } + + @Override + public List getBacklinksByTitle(String title) { + return wikiRemoteDataSource.getBacklinksByTitle(title); + } +} diff --git a/src/main/java/rar/java/wiki/WikiRemoteDataSource.java b/src/main/java/rar/java/wiki/data/source/WikiRemoteDataSource.java similarity index 82% rename from src/main/java/rar/java/wiki/WikiRemoteDataSource.java rename to src/main/java/rar/java/wiki/data/source/WikiRemoteDataSource.java index a87a8e4..7301947 100644 --- a/src/main/java/rar/java/wiki/WikiRemoteDataSource.java +++ b/src/main/java/rar/java/wiki/data/source/WikiRemoteDataSource.java @@ -1,4 +1,4 @@ -package rar.java.wiki; +package rar.java.wiki.data.source; import java.util.List; diff --git a/src/main/java/rar/java/wiki/domain/repository/WikiRepository.java b/src/main/java/rar/java/wiki/domain/repository/WikiRepository.java new file mode 100644 index 0000000..bc7a20c --- /dev/null +++ b/src/main/java/rar/java/wiki/domain/repository/WikiRepository.java @@ -0,0 +1,8 @@ +package rar.java.wiki.domain.repository; + +import java.util.List; + +public interface WikiRepository { + List getLinksByTitle(String title); + List getBacklinksByTitle(String title); +} diff --git a/src/main/java/rar/java/wiki/WikiRemoteDataSourceImpl.java b/src/main/java/rar/java/wiki/remote/WikiRemoteDataSourceImpl.java similarity index 72% rename from src/main/java/rar/java/wiki/WikiRemoteDataSourceImpl.java rename to src/main/java/rar/java/wiki/remote/WikiRemoteDataSourceImpl.java index 9baca9a..b3384b6 100644 --- a/src/main/java/rar/java/wiki/WikiRemoteDataSourceImpl.java +++ b/src/main/java/rar/java/wiki/remote/WikiRemoteDataSourceImpl.java @@ -1,4 +1,4 @@ -package rar.java.wiki; +package rar.java.wiki.remote; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; @@ -7,6 +7,7 @@ import io.github.resilience4j.ratelimiter.RateLimiterRegistry; import org.apache.http.client.utils.URIBuilder; import org.jetbrains.annotations.NotNull; +import rar.java.wiki.data.source.WikiRemoteDataSource; import rar.kotlin.model.Link; import rar.kotlin.model.WikiBacklinksResponse; import rar.kotlin.model.WikiLinksResponse; @@ -22,33 +23,32 @@ public class WikiRemoteDataSourceImpl implements WikiRemoteDataSource { private static final String URL = "https://ru.wikipedia.org/w/api.php"; private static final RateLimiterConfig config = RateLimiterConfig.custom() - .limitRefreshPeriod(Duration.ofMillis(40)) - .limitForPeriod(1) - .timeoutDuration(Duration.ofDays(100000)) - .build(); + .limitRefreshPeriod(Duration.ofMillis(40)) + .limitForPeriod(1) + .timeoutDuration(Duration.ofDays(100000)) + .build(); private static final RateLimiterRegistry rateLimiterRegistry = RateLimiterRegistry.of(config); private static final RateLimiter rateLimiter = rateLimiterRegistry.rateLimiter("rate"); private static final ObjectMapper objectMapper = new ObjectMapper() - .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + + private static final HttpClient httpClient = HttpClient.newHttpClient(); @Override public List getLinksByTitle(String title) { try { String responseBody = RateLimiter.decorateCheckedSupplier(rateLimiter, () -> - HttpClient.newBuilder() - .build() - .send( - HttpRequest.newBuilder() - .uri(getUriBuilder(title).build()) - .GET() - .build(), - HttpResponse.BodyHandlers.ofString() + httpClient.send( + HttpRequest.newBuilder() + .uri(getUriBuilder(title).build()) + .GET() + .build(), + HttpResponse.BodyHandlers.ofString() ) .body() ).get(); -// System.out.println("Got links from: " + title); - WikiLinksResponse response = objectMapper.readValue(responseBody, WikiLinksResponse.class); + WikiLinksResponse response = objectMapper.readValue(responseBody, WikiLinksResponse.class); return parseResponse(response); } catch (Throwable e) { throw new RuntimeException(e); @@ -70,27 +70,24 @@ private static URIBuilder getUriBuilder(String title) throws URISyntaxException @NotNull private static List parseResponse(WikiLinksResponse response) { return response.getQuery().getPages().entrySet().iterator().next().getValue().getLinks() - .stream() - .map(Link::getTitle) - .toList(); + .stream() + .map(Link::getTitle) + .toList(); } @Override public List getBacklinksByTitle(String title) { try { String responseBody = RateLimiter.decorateCheckedSupplier(rateLimiter, () -> - HttpClient.newBuilder() - .build() - .send( - HttpRequest.newBuilder() - .uri(getBacklinksUriBuilder(title).build()) - .GET() - .build(), - HttpResponse.BodyHandlers.ofString() - ) - .body() + httpClient.send( + HttpRequest.newBuilder() + .uri(getBacklinksUriBuilder(title).build()) + .GET() + .build(), + HttpResponse.BodyHandlers.ofString() + ) + .body() ).get(); -// System.out.println("Got links from: " + title); WikiBacklinksResponse response = objectMapper.readValue(responseBody, WikiBacklinksResponse.class); return parseBacklinksResponse(response); From 8081b0e2bb022a52e4e8437b0be28c5c0ce37e3a Mon Sep 17 00:00:00 2001 From: Daniil Lyubaev Date: Mon, 2 Oct 2023 13:08:55 +0300 Subject: [PATCH 49/58] Cached thread pool --- src/main/java/rar/java/repository/WikiGameExecutorImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/rar/java/repository/WikiGameExecutorImpl.java b/src/main/java/rar/java/repository/WikiGameExecutorImpl.java index a623125..6c5af39 100644 --- a/src/main/java/rar/java/repository/WikiGameExecutorImpl.java +++ b/src/main/java/rar/java/repository/WikiGameExecutorImpl.java @@ -23,7 +23,7 @@ public List play(@NotNull String startPageTitle, @NotNull String endPage Queue parsedPages = new ConcurrentLinkedQueue<>(); Set receivedLinks = new ConcurrentSkipListSet<>(); - ExecutorService exec = Executors.newVirtualThreadPerTaskExecutor(); + ExecutorService exec = Executors.newCachedThreadPool(); do { exec.execute(makeSearch(rawPages, parsedPages, receivedLinks, endPageTitle)); From 1c287bd7a2ebed2053162986db744d4e027396dd Mon Sep 17 00:00:00 2001 From: Daniil Lyubaev Date: Mon, 2 Oct 2023 14:06:39 +0300 Subject: [PATCH 50/58] Refactor --- .../java/repository/WikiGameExecutorImpl.java | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/main/java/rar/java/repository/WikiGameExecutorImpl.java b/src/main/java/rar/java/repository/WikiGameExecutorImpl.java index 6c5af39..8c7e64a 100644 --- a/src/main/java/rar/java/repository/WikiGameExecutorImpl.java +++ b/src/main/java/rar/java/repository/WikiGameExecutorImpl.java @@ -18,18 +18,18 @@ public class WikiGameExecutorImpl implements WikiGame { @NotNull @Override public List play(@NotNull String startPageTitle, @NotNull String endPageTitle, int maxDepth) { - var startedPage = new Page(startPageTitle, null); - Queue rawPages = new ConcurrentLinkedQueue<>(Collections.singleton(startedPage)); + var startPage = new Page(startPageTitle, null); + Queue rawPages = new ConcurrentLinkedQueue<>(Collections.singleton(startPage)); Queue parsedPages = new ConcurrentLinkedQueue<>(); Set receivedLinks = new ConcurrentSkipListSet<>(); - ExecutorService exec = Executors.newCachedThreadPool(); + var executor = Executors.newCachedThreadPool(); do { - exec.execute(makeSearch(rawPages, parsedPages, receivedLinks, endPageTitle)); + executor.execute(makeSearch(rawPages, parsedPages, receivedLinks, endPageTitle)); } while (!isFinished.get()); - exec.shutdown(); - exec.close(); + executor.shutdown(); + executor.close(); parsedPages.add( new Page(endPageTitle, @@ -45,14 +45,14 @@ public List play(@NotNull String startPageTitle, @NotNull String endPage public Runnable makeSearch(Queue rawPages, Queue parsedPages, Set receivedLinks, String endPageTitle) { return () -> { - Page curPage = rawPages.poll(); - if (curPage != null) { - List newLinks = wikiRemoteDataSource.getLinksByTitle(curPage.getTitle()); + Page currentPage = rawPages.poll(); + if (currentPage != null) { + List newLinks = wikiRemoteDataSource.getLinksByTitle(currentPage.getTitle()); if (newLinks != null) { - parsedPages.add(curPage); + parsedPages.add(currentPage); for (String link : newLinks) { if (receivedLinks.add(link)) { - rawPages.add(new Page(link, curPage)); + rawPages.add(new Page(link, currentPage)); } if (endPageTitle.equals(link)) { isFinished.set(true); @@ -60,7 +60,7 @@ public Runnable makeSearch(Queue rawPages, Queue parsedPages, Set rawPages, Queue parsedPages, Set getResultPath(Queue parsedPages, String endPageTitle) { var path = new ArrayList(); - var curPage = parsedPages.stream() + var currentPage = parsedPages.stream() .filter(p -> p.getTitle().equals(endPageTitle)) .findAny() .orElseThrow(); - while (curPage.getParentPage() != null) { - curPage = curPage.getParentPage(); - path.add(curPage.getTitle()); + while (currentPage.getParentPage() != null) { + currentPage = currentPage.getParentPage(); + path.add(currentPage.getTitle()); } Collections.reverse(path); // Reverse the order of elements in the list return path; From 2fb93d88a39e72aff98c294801814cbc0158c22e Mon Sep 17 00:00:00 2001 From: Daniil Lyubaev Date: Mon, 2 Oct 2023 14:07:28 +0300 Subject: [PATCH 51/58] Refactor --- src/main/java/rar/java/Main.java | 4 ++-- ...{WikiRepositoryImpl.java => WikiRemoteRepositoryImpl.java} | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename src/main/java/rar/java/wiki/data/repository/{WikiRepositoryImpl.java => WikiRemoteRepositoryImpl.java} (79%) diff --git a/src/main/java/rar/java/Main.java b/src/main/java/rar/java/Main.java index 361bf95..19f7181 100644 --- a/src/main/java/rar/java/Main.java +++ b/src/main/java/rar/java/Main.java @@ -1,6 +1,6 @@ package rar.java; -import rar.java.wiki.data.repository.WikiRepositoryImpl; +import rar.java.wiki.data.repository.WikiRemoteRepositoryImpl; import rar.java.wiki.data.source.WikiRemoteDataSource; import rar.java.wiki.domain.repository.WikiRepository; import rar.java.wiki.remote.WikiRemoteDataSourceImpl; @@ -9,7 +9,7 @@ public class Main { public static void main(String[] args) { WikiRemoteDataSource wikiRemoteDataSource = new WikiRemoteDataSourceImpl(); - WikiRepository wikiRepository = new WikiRepositoryImpl(wikiRemoteDataSource); + WikiRepository wikiRepository = new WikiRemoteRepositoryImpl(wikiRemoteDataSource); long startTime = System.currentTimeMillis(); diff --git a/src/main/java/rar/java/wiki/data/repository/WikiRepositoryImpl.java b/src/main/java/rar/java/wiki/data/repository/WikiRemoteRepositoryImpl.java similarity index 79% rename from src/main/java/rar/java/wiki/data/repository/WikiRepositoryImpl.java rename to src/main/java/rar/java/wiki/data/repository/WikiRemoteRepositoryImpl.java index 6bcf265..a981410 100644 --- a/src/main/java/rar/java/wiki/data/repository/WikiRepositoryImpl.java +++ b/src/main/java/rar/java/wiki/data/repository/WikiRemoteRepositoryImpl.java @@ -5,11 +5,11 @@ import java.util.List; -public class WikiRepositoryImpl implements WikiRepository { +public class WikiRemoteRepositoryImpl implements WikiRepository { private final WikiRemoteDataSource wikiRemoteDataSource; - public WikiRepositoryImpl(WikiRemoteDataSource wikiRemoteDataSource) { + public WikiRemoteRepositoryImpl(WikiRemoteDataSource wikiRemoteDataSource) { this.wikiRemoteDataSource = wikiRemoteDataSource; } From c90c1f5de0c620bbf945d7f8bdfb68342a880815 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A8=D0=B0=D1=85=D0=BE=D0=B2=20=D0=90=D0=BB=D0=B5=D0=BA?= =?UTF-8?q?=D1=81=D0=B0=D0=BD=D0=B4=D1=80?= Date: Thu, 5 Oct 2023 14:36:17 +0300 Subject: [PATCH 52/58] Add DB --- README.md | 1 + build.gradle.kts | 4 ++ src/main/java/rar/java/Main.java | 19 +++--- .../rar/java/repository/LoomAlgoImpl.java | 2 - .../java/rar/java/repository/LoomImpl.java | 16 ++--- .../java/repository/WikiGameExecutorImpl.java | 8 +-- .../java/repository/WikiGameFutureImpl.java | 8 +-- .../java/repository/WikiGameSerialImpl.java | 8 +-- .../repository/WikiRemoteRepositoryImpl.java | 26 -------- .../data/repository/WikiRepositoryImpl.java | 26 ++++++++ ...oteDataSource.java => WikiDataSource.java} | 2 +- .../source/WikiDataSourceImpl.java} | 5 +- .../data/source/WikiMySqlDataSourceImpl.java | 65 +++++++++++++++++++ 13 files changed, 127 insertions(+), 63 deletions(-) delete mode 100644 src/main/java/rar/java/wiki/data/repository/WikiRemoteRepositoryImpl.java create mode 100644 src/main/java/rar/java/wiki/data/repository/WikiRepositoryImpl.java rename src/main/java/rar/java/wiki/data/source/{WikiRemoteDataSource.java => WikiDataSource.java} (80%) rename src/main/java/rar/java/wiki/{remote/WikiRemoteDataSourceImpl.java => data/source/WikiDataSourceImpl.java} (96%) create mode 100644 src/main/java/rar/java/wiki/data/source/WikiMySqlDataSourceImpl.java diff --git a/README.md b/README.md index e69de29..2efc739 100644 --- a/README.md +++ b/README.md @@ -0,0 +1 @@ +https://dumps.wikimedia.org/ruwiki/latest/ diff --git a/build.gradle.kts b/build.gradle.kts index 1441902..7c72dae 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -45,6 +45,10 @@ dependencies { implementation("org.apache.httpcomponents:httpclient:4.5.13") implementation("io.github.resilience4j:resilience4j-timelimiter:2.1.0") implementation("io.github.resilience4j:resilience4j-ratelimiter:2.1.0") + + // mysql + val jasyncVersion = "2.2.0" + implementation("com.github.jasync-sql:jasync-mysql:${jasyncVersion}") } tasks.test { diff --git a/src/main/java/rar/java/Main.java b/src/main/java/rar/java/Main.java index 19f7181..e5882db 100644 --- a/src/main/java/rar/java/Main.java +++ b/src/main/java/rar/java/Main.java @@ -1,23 +1,20 @@ package rar.java; -import rar.java.wiki.data.repository.WikiRemoteRepositoryImpl; -import rar.java.wiki.data.source.WikiRemoteDataSource; +import rar.java.wiki.data.repository.WikiRepositoryImpl; +import rar.java.wiki.data.source.WikiMySqlDataSourceImpl; +import rar.java.wiki.data.source.WikiDataSource; import rar.java.wiki.domain.repository.WikiRepository; -import rar.java.wiki.remote.WikiRemoteDataSourceImpl; import rar.java.repository.*; public class Main { public static void main(String[] args) { - WikiRemoteDataSource wikiRemoteDataSource = new WikiRemoteDataSourceImpl(); - WikiRepository wikiRepository = new WikiRemoteRepositoryImpl(wikiRemoteDataSource); + WikiDataSource wikiDataSource = new WikiMySqlDataSourceImpl(); + WikiRepository wikiRepository = new WikiRepositoryImpl(wikiDataSource); - long startTime = System.currentTimeMillis(); - - WikiGame wikiGame = new LoomImpl(wikiRepository); -// var path = wikiGame.play("Алгебра", "Ятаган", 6); -// var path = wikiGame.play("!!!", "Теория гомологий", 6); - var path = wikiGame.play("Бакуган", "Библия", 6); + WikiGame wikiGame = new LoomAlgoImpl(wikiRepository); + long startTime = System.currentTimeMillis(); + var path = wikiGame.play("Охотники_за_привидениями", "Пуджа", 6); long endTime = System.currentTimeMillis(); System.out.println(path); diff --git a/src/main/java/rar/java/repository/LoomAlgoImpl.java b/src/main/java/rar/java/repository/LoomAlgoImpl.java index 381d1c5..46e8a11 100644 --- a/src/main/java/rar/java/repository/LoomAlgoImpl.java +++ b/src/main/java/rar/java/repository/LoomAlgoImpl.java @@ -1,9 +1,7 @@ package rar.java.repository; import jdk.incubator.concurrent.StructuredTaskScope; -import rar.java.wiki.data.source.WikiRemoteDataSource; import rar.java.wiki.domain.repository.WikiRepository; -import rar.java.wiki.remote.WikiRemoteDataSourceImpl; import rar.kotlin.model.BackwardPage; import rar.kotlin.model.ForwardPage; diff --git a/src/main/java/rar/java/repository/LoomImpl.java b/src/main/java/rar/java/repository/LoomImpl.java index d8ddd4e..9f8c0a5 100644 --- a/src/main/java/rar/java/repository/LoomImpl.java +++ b/src/main/java/rar/java/repository/LoomImpl.java @@ -6,6 +6,7 @@ import java.util.*; import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicBoolean; public class LoomImpl implements WikiGame { @@ -36,12 +37,12 @@ public List play(String startPageTitle, String endPageTitle, int maxDept } private Page processPage( - Page page, - String endPageTitle, - int curDepth, - int maxDepth, - Map visitedPages - ) { + Page page, + String endPageTitle, + int curDepth, + int maxDepth, + Map visitedPages) { + if (visitedPages.putIfAbsent(page.getTitle(), true) != null) { throw new RuntimeException("Already visited"); } @@ -63,8 +64,7 @@ private Page processPage( endPageTitle, curDepth + 1, maxDepth, - visitedPages - ) + visitedPages) ); }); diff --git a/src/main/java/rar/java/repository/WikiGameExecutorImpl.java b/src/main/java/rar/java/repository/WikiGameExecutorImpl.java index b818503..bc1c9c8 100644 --- a/src/main/java/rar/java/repository/WikiGameExecutorImpl.java +++ b/src/main/java/rar/java/repository/WikiGameExecutorImpl.java @@ -1,8 +1,8 @@ package rar.java.repository; import org.jetbrains.annotations.NotNull; -import rar.java.wiki.data.source.WikiRemoteDataSource; -import rar.java.wiki.remote.WikiRemoteDataSourceImpl; +import rar.java.wiki.data.source.WikiDataSource; +import rar.java.wiki.data.source.WikiDataSourceImpl; import rar.kotlin.model.Page; import java.util.*; @@ -13,7 +13,7 @@ public class WikiGameExecutorImpl implements WikiGame { private static AtomicBoolean isFinished = new AtomicBoolean(false); - private final WikiRemoteDataSource wikiRemoteDataSource = new WikiRemoteDataSourceImpl(); + private final WikiDataSource wikiDataSource = new WikiDataSourceImpl(); @NotNull @Override @@ -47,7 +47,7 @@ public Runnable makeSearch(Queue rawPages, Queue parsedPages, Set { Page currentPage = rawPages.poll(); if (currentPage != null) { - List newLinks = wikiRemoteDataSource.getLinksByTitle(currentPage.getTitle()); + List newLinks = wikiDataSource.getLinksByTitle(currentPage.getTitle()); if (newLinks != null) { parsedPages.add(currentPage); for (String link : newLinks) { diff --git a/src/main/java/rar/java/repository/WikiGameFutureImpl.java b/src/main/java/rar/java/repository/WikiGameFutureImpl.java index 0c4a48f..cc3732a 100644 --- a/src/main/java/rar/java/repository/WikiGameFutureImpl.java +++ b/src/main/java/rar/java/repository/WikiGameFutureImpl.java @@ -3,8 +3,8 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import org.jetbrains.annotations.NotNull; -import rar.java.wiki.data.source.WikiRemoteDataSource; -import rar.java.wiki.remote.WikiRemoteDataSourceImpl; +import rar.java.wiki.data.source.WikiDataSource; +import rar.java.wiki.data.source.WikiDataSourceImpl; import rar.kotlin.model.Page; import java.util.*; @@ -12,7 +12,7 @@ public class WikiGameFutureImpl implements WikiGame { - private static final WikiRemoteDataSource wikiRemoteDataSource = new WikiRemoteDataSourceImpl(); + private static final WikiDataSource WIKI_DATA_SOURCE = new WikiDataSourceImpl(); @NotNull @Override @@ -80,6 +80,6 @@ private List getChildLinks(String title) { ObjectMapper objectMapper = new ObjectMapper(); objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - return wikiRemoteDataSource.getLinksByTitle(title); + return WIKI_DATA_SOURCE.getLinksByTitle(title); } } diff --git a/src/main/java/rar/java/repository/WikiGameSerialImpl.java b/src/main/java/rar/java/repository/WikiGameSerialImpl.java index 1ca7414..0111a90 100644 --- a/src/main/java/rar/java/repository/WikiGameSerialImpl.java +++ b/src/main/java/rar/java/repository/WikiGameSerialImpl.java @@ -1,8 +1,8 @@ package rar.java.repository; import org.jetbrains.annotations.NotNull; -import rar.java.wiki.data.source.WikiRemoteDataSource; -import rar.java.wiki.remote.WikiRemoteDataSourceImpl; +import rar.java.wiki.data.source.WikiDataSource; +import rar.java.wiki.data.source.WikiDataSourceImpl; import rar.kotlin.model.Page; import java.util.*; @@ -10,7 +10,7 @@ public class WikiGameSerialImpl implements WikiGame { private static final String URL = "https://ru.wikipedia.org/w/api.php"; - private final WikiRemoteDataSource wikiRemoteDataSource = new WikiRemoteDataSourceImpl(); + private final WikiDataSource wikiDataSource = new WikiDataSourceImpl(); @NotNull @Override @@ -26,7 +26,7 @@ public List play(String startPageTitle, String endPageTitle, int maxDept System.out.println("parsedTitle size = " + parsedTitle.size()); var curPage = rawPages.poll(); parentEndPage = curPage; - var newLinks = wikiRemoteDataSource.getLinksByTitle(curPage.getTitle()); + var newLinks = wikiDataSource.getLinksByTitle(curPage.getTitle()); parsedPages.add(curPage); parsedTitle.addAll(newLinks); rawPages.addAll( diff --git a/src/main/java/rar/java/wiki/data/repository/WikiRemoteRepositoryImpl.java b/src/main/java/rar/java/wiki/data/repository/WikiRemoteRepositoryImpl.java deleted file mode 100644 index a981410..0000000 --- a/src/main/java/rar/java/wiki/data/repository/WikiRemoteRepositoryImpl.java +++ /dev/null @@ -1,26 +0,0 @@ -package rar.java.wiki.data.repository; - -import rar.java.wiki.data.source.WikiRemoteDataSource; -import rar.java.wiki.domain.repository.WikiRepository; - -import java.util.List; - -public class WikiRemoteRepositoryImpl implements WikiRepository { - - private final WikiRemoteDataSource wikiRemoteDataSource; - - public WikiRemoteRepositoryImpl(WikiRemoteDataSource wikiRemoteDataSource) { - this.wikiRemoteDataSource = wikiRemoteDataSource; - } - - - @Override - public List getLinksByTitle(String title) { - return wikiRemoteDataSource.getLinksByTitle(title); - } - - @Override - public List getBacklinksByTitle(String title) { - return wikiRemoteDataSource.getBacklinksByTitle(title); - } -} diff --git a/src/main/java/rar/java/wiki/data/repository/WikiRepositoryImpl.java b/src/main/java/rar/java/wiki/data/repository/WikiRepositoryImpl.java new file mode 100644 index 0000000..d7c0637 --- /dev/null +++ b/src/main/java/rar/java/wiki/data/repository/WikiRepositoryImpl.java @@ -0,0 +1,26 @@ +package rar.java.wiki.data.repository; + +import rar.java.wiki.data.source.WikiDataSource; +import rar.java.wiki.domain.repository.WikiRepository; + +import java.util.List; + +public class WikiRepositoryImpl implements WikiRepository { + + private final WikiDataSource wikiDataSource; + + public WikiRepositoryImpl(WikiDataSource wikiDataSource) { + this.wikiDataSource = wikiDataSource; + } + + + @Override + public List getLinksByTitle(String title) { + return wikiDataSource.getLinksByTitle(title); + } + + @Override + public List getBacklinksByTitle(String title) { + return wikiDataSource.getBacklinksByTitle(title); + } +} diff --git a/src/main/java/rar/java/wiki/data/source/WikiRemoteDataSource.java b/src/main/java/rar/java/wiki/data/source/WikiDataSource.java similarity index 80% rename from src/main/java/rar/java/wiki/data/source/WikiRemoteDataSource.java rename to src/main/java/rar/java/wiki/data/source/WikiDataSource.java index 7301947..1dcc6ce 100644 --- a/src/main/java/rar/java/wiki/data/source/WikiRemoteDataSource.java +++ b/src/main/java/rar/java/wiki/data/source/WikiDataSource.java @@ -2,7 +2,7 @@ import java.util.List; -public interface WikiRemoteDataSource { +public interface WikiDataSource { List getLinksByTitle(String title); List getBacklinksByTitle(String title); } diff --git a/src/main/java/rar/java/wiki/remote/WikiRemoteDataSourceImpl.java b/src/main/java/rar/java/wiki/data/source/WikiDataSourceImpl.java similarity index 96% rename from src/main/java/rar/java/wiki/remote/WikiRemoteDataSourceImpl.java rename to src/main/java/rar/java/wiki/data/source/WikiDataSourceImpl.java index b3384b6..3d67455 100644 --- a/src/main/java/rar/java/wiki/remote/WikiRemoteDataSourceImpl.java +++ b/src/main/java/rar/java/wiki/data/source/WikiDataSourceImpl.java @@ -1,4 +1,4 @@ -package rar.java.wiki.remote; +package rar.java.wiki.data.source; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; @@ -7,7 +7,6 @@ import io.github.resilience4j.ratelimiter.RateLimiterRegistry; import org.apache.http.client.utils.URIBuilder; import org.jetbrains.annotations.NotNull; -import rar.java.wiki.data.source.WikiRemoteDataSource; import rar.kotlin.model.Link; import rar.kotlin.model.WikiBacklinksResponse; import rar.kotlin.model.WikiLinksResponse; @@ -19,7 +18,7 @@ import java.time.Duration; import java.util.List; -public class WikiRemoteDataSourceImpl implements WikiRemoteDataSource { +public class WikiDataSourceImpl implements WikiDataSource { private static final String URL = "https://ru.wikipedia.org/w/api.php"; private static final RateLimiterConfig config = RateLimiterConfig.custom() diff --git a/src/main/java/rar/java/wiki/data/source/WikiMySqlDataSourceImpl.java b/src/main/java/rar/java/wiki/data/source/WikiMySqlDataSourceImpl.java new file mode 100644 index 0000000..90a2955 --- /dev/null +++ b/src/main/java/rar/java/wiki/data/source/WikiMySqlDataSourceImpl.java @@ -0,0 +1,65 @@ +package rar.java.wiki.data.source; + + +import com.github.jasync.sql.db.Connection; +import com.github.jasync.sql.db.mysql.MySQLConnectionBuilder; +import io.github.resilience4j.ratelimiter.RateLimiter; +import io.github.resilience4j.ratelimiter.RateLimiterConfig; +import io.github.resilience4j.ratelimiter.RateLimiterRegistry; + +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +public class WikiMySqlDataSourceImpl implements WikiDataSource { + private static final RateLimiterConfig config = RateLimiterConfig.custom() + .limitRefreshPeriod(Duration.ofMillis(100)) + .limitForPeriod(1) + .timeoutDuration(Duration.ofDays(100000)) + .build(); + private static final RateLimiterRegistry rateLimiterRegistry = RateLimiterRegistry.of(config); + private static final RateLimiter rateLimiter = rateLimiterRegistry.rateLimiter("rate"); + + // Connection to MySQL DB + Connection connection = MySQLConnectionBuilder.createConnectionPool( + "jdbc:mysql://localhost:3306/wiki?user=root&password=2473538238"); + + @Override + public List getLinksByTitle(String title) { + try { + var queryResult = RateLimiter.decorateCheckedSupplier(rateLimiter, () -> + connection.sendPreparedStatement( + "SELECT pl_title from pagelinks join page on page_id = pl_from where page_title = ? and pl_namespace = 0", + Collections.singletonList(title) + ).join()); + + return queryResult.get().getRows().stream() + .map(row -> row.get(0)) + .map(bytes -> new String((byte[]) bytes, StandardCharsets.UTF_8)) + .toList(); + } catch (Throwable e) { + throw new RuntimeException(e); + } + } + + @Override + public List getBacklinksByTitle(String title) { + try { + var queryResult = RateLimiter.decorateCheckedSupplier(rateLimiter, () -> + connection.sendPreparedStatement( + "SELECT pl_title from pagelinks join page on page_id = pl_from where page_title = ? and pl_namespace = 0", + Collections.singletonList(title) + ).join()); + + return queryResult.get().getRows().stream() + .map(row -> row.get(0)) + .filter(Objects::nonNull) + .map(bytes -> new String((byte[]) bytes, StandardCharsets.UTF_8)) + .toList(); + } catch (Throwable e) { + throw new RuntimeException(e); + } + } +} From d818d17978687610bec51518e128ddc8a638c725 Mon Sep 17 00:00:00 2001 From: Daniil Lyubaev Date: Sat, 7 Oct 2023 14:35:48 +0300 Subject: [PATCH 53/58] Fix executors --- .../java/rar/java/repository/WikiGameExecutorImpl.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/rar/java/repository/WikiGameExecutorImpl.java b/src/main/java/rar/java/repository/WikiGameExecutorImpl.java index bc1c9c8..0702e58 100644 --- a/src/main/java/rar/java/repository/WikiGameExecutorImpl.java +++ b/src/main/java/rar/java/repository/WikiGameExecutorImpl.java @@ -47,7 +47,13 @@ public Runnable makeSearch(Queue rawPages, Queue parsedPages, Set { Page currentPage = rawPages.poll(); if (currentPage != null) { - List newLinks = wikiDataSource.getLinksByTitle(currentPage.getTitle()); + List newLinks; + try { + newLinks = wikiDataSource.getLinksByTitle(currentPage.getTitle()); + } catch (Throwable e) { + newLinks = null; + } + if (newLinks != null) { parsedPages.add(currentPage); for (String link : newLinks) { From 793e6804b9b885c521e43f20e275330df699778d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A8=D0=B0=D1=85=D0=BE=D0=B2=20=D0=90=D0=BB=D0=B5=D0=BA?= =?UTF-8?q?=D1=81=D0=B0=D0=BD=D0=B4=D1=80?= Date: Sat, 7 Oct 2023 15:36:09 +0300 Subject: [PATCH 54/58] Fix SQL request --- .../java/rar/java/wiki/data/source/WikiMySqlDataSourceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/rar/java/wiki/data/source/WikiMySqlDataSourceImpl.java b/src/main/java/rar/java/wiki/data/source/WikiMySqlDataSourceImpl.java index 90a2955..931a33e 100644 --- a/src/main/java/rar/java/wiki/data/source/WikiMySqlDataSourceImpl.java +++ b/src/main/java/rar/java/wiki/data/source/WikiMySqlDataSourceImpl.java @@ -49,7 +49,7 @@ public List getBacklinksByTitle(String title) { try { var queryResult = RateLimiter.decorateCheckedSupplier(rateLimiter, () -> connection.sendPreparedStatement( - "SELECT pl_title from pagelinks join page on page_id = pl_from where page_title = ? and pl_namespace = 0", + "SELECT page_title from pagelinks join page on pl_from = page_id where pl_title = ? and pl_namespace = 0;", Collections.singletonList(title) ).join()); From a612623c97ff32ed0bae15971c7e74f4198f01f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A8=D0=B0=D1=85=D0=BE=D0=B2=20=D0=90=D0=BB=D0=B5=D0=BA?= =?UTF-8?q?=D1=81=D0=B0=D0=BD=D0=B4=D1=80?= Date: Sun, 8 Oct 2023 22:29:14 +0300 Subject: [PATCH 55/58] Fix SQL request --- .../java/rar/java/wiki/data/source/WikiMySqlDataSourceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/rar/java/wiki/data/source/WikiMySqlDataSourceImpl.java b/src/main/java/rar/java/wiki/data/source/WikiMySqlDataSourceImpl.java index 931a33e..13b9ece 100644 --- a/src/main/java/rar/java/wiki/data/source/WikiMySqlDataSourceImpl.java +++ b/src/main/java/rar/java/wiki/data/source/WikiMySqlDataSourceImpl.java @@ -24,7 +24,7 @@ public class WikiMySqlDataSourceImpl implements WikiDataSource { // Connection to MySQL DB Connection connection = MySQLConnectionBuilder.createConnectionPool( - "jdbc:mysql://localhost:3306/wiki?user=root&password=2473538238"); + "jdbc:mysql://localhost:3306/wiki?user=root&password=123456789"); @Override public List getLinksByTitle(String title) { From 76beac27e8765c8a44bc50ce46523604a1552779 Mon Sep 17 00:00:00 2001 From: Daniil Lyubaev Date: Mon, 9 Oct 2023 11:51:26 +0300 Subject: [PATCH 56/58] Readme --- README.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2efc739..d890335 100644 --- a/README.md +++ b/README.md @@ -1 +1,17 @@ -https://dumps.wikimedia.org/ruwiki/latest/ +# Thread Wars: Войны клонов на страницах Wiki + +### Правила +Описаны тут: https://telegra.ph/WikiGame-10-07 + +### Что тут есть +В исходниках Java, в папке `repository`, лежит интерфейс `WikiGame` -- его нужно реализовать. + +Рядом с этим интерфейсом лежат разные реализации этого интерфейса -- начиная от `Executors`, и заканчивая алгоритмическим решением на `Loom`. + +В исходниках для Kotlin лежит реализация с корутинами. + +### Как работать +Нужно форкнуть себе репозиторий, написать решение, и сделать PR в `main`-ветку. + +### Полезное +Дампы ру-википедии для MySQL: https://dumps.wikimedia.org/ruwiki/latest/ From 49147fdbbf92b8466e8ec58c54fa40d95d85e651 Mon Sep 17 00:00:00 2001 From: Daniil Lyubaev Date: Mon, 9 Oct 2023 13:19:13 +0300 Subject: [PATCH 57/58] Readme --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index d890335..5c0f911 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ # Thread Wars: Войны клонов на страницах Wiki +### Чат книжного клуба .rar +https://t.me/point_rar_chat + ### Правила Описаны тут: https://telegra.ph/WikiGame-10-07 From a6f44a97c7ccdddada29e37ab1169c7b12edf9cb Mon Sep 17 00:00:00 2001 From: Vlad Mamaev Date: Sun, 15 Oct 2023 16:45:16 +0300 Subject: [PATCH 58/58] add ReactorAlgoWikiGameImpl --- build.gradle.kts | 2 + src/main/java/rar/java/Main.java | 2 +- .../repository/ReactorAlgoWikiGameImpl.java | 100 ++++++++++++++++++ 3 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 src/main/java/rar/java/repository/ReactorAlgoWikiGameImpl.java diff --git a/build.gradle.kts b/build.gradle.kts index 7c72dae..4a80778 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -46,6 +46,8 @@ dependencies { implementation("io.github.resilience4j:resilience4j-timelimiter:2.1.0") implementation("io.github.resilience4j:resilience4j-ratelimiter:2.1.0") + implementation("io.projectreactor:reactor-core:3.5.10") + // mysql val jasyncVersion = "2.2.0" implementation("com.github.jasync-sql:jasync-mysql:${jasyncVersion}") diff --git a/src/main/java/rar/java/Main.java b/src/main/java/rar/java/Main.java index e5882db..b06856a 100644 --- a/src/main/java/rar/java/Main.java +++ b/src/main/java/rar/java/Main.java @@ -11,7 +11,7 @@ public static void main(String[] args) { WikiDataSource wikiDataSource = new WikiMySqlDataSourceImpl(); WikiRepository wikiRepository = new WikiRepositoryImpl(wikiDataSource); - WikiGame wikiGame = new LoomAlgoImpl(wikiRepository); + WikiGame wikiGame = new ReactorAlgoWikiGameImpl(wikiRepository); long startTime = System.currentTimeMillis(); var path = wikiGame.play("Охотники_за_привидениями", "Пуджа", 6); diff --git a/src/main/java/rar/java/repository/ReactorAlgoWikiGameImpl.java b/src/main/java/rar/java/repository/ReactorAlgoWikiGameImpl.java new file mode 100644 index 0000000..4e4e450 --- /dev/null +++ b/src/main/java/rar/java/repository/ReactorAlgoWikiGameImpl.java @@ -0,0 +1,100 @@ +package rar.java.repository; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Function; + +import rar.java.wiki.domain.repository.WikiRepository; +import rar.kotlin.model.BackwardPage; +import rar.kotlin.model.ForwardPage; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.core.scheduler.Schedulers; + +public class ReactorAlgoWikiGameImpl implements WikiGame { + + + private record PairPages(ForwardPage forwardPage, BackwardPage backwardPage) { + } + + + private final WikiRepository wikiRepository; + + public ReactorAlgoWikiGameImpl(WikiRepository wikiRepository) { + this.wikiRepository = wikiRepository; + } + + @Override + public List play(String startPageTitle, String endPageTitle, int maxDepth) { + var visitedForwardPages = new ConcurrentHashMap(); + var visitedBackwardPages = new ConcurrentHashMap(); + + var startForwardPage = new ForwardPage(startPageTitle, null); + var endBackwardPage = new BackwardPage(endPageTitle, null); + + PairPages pairPagesResult = Flux.firstWithValue( + Mono.just(startForwardPage) + .expand(page -> getLinks(page) + .map(link -> new ForwardPage(link, page)) + .filter(page2 -> visitedForwardPages.putIfAbsent(page2.getTitle(), page2) == null) + ) + .filter(page -> visitedBackwardPages.containsKey(page.getTitle())) + .map(page -> new PairPages(page, visitedBackwardPages.get(page.getTitle()))), + + + Mono.just(endBackwardPage) + .expand(page -> getBackwardLinks(page) + .map(link -> new BackwardPage(link, page)) + .filter(page2 -> visitedBackwardPages.putIfAbsent(page2.getTitle(), page2) == null) + ) + .filter(page -> visitedForwardPages.containsKey(page.getTitle())) + .map(page -> new PairPages(visitedForwardPages.get(page.getTitle()), page)) + ) + .blockFirst(); + + return getFinalPathFromForwardAndBackward(pairPagesResult.forwardPage, pairPagesResult.backwardPage); + } + + private Flux getLinks(ForwardPage page) { + return Mono.fromCallable(() -> wikiRepository.getLinksByTitle(page.getTitle())) + .subscribeOn(Schedulers.boundedElastic()) + .flatMapIterable(Function.identity()); + } + + private Flux getBackwardLinks(BackwardPage page) { + return Mono.fromCallable(() -> wikiRepository.getBacklinksByTitle(page.getTitle())) + .subscribeOn(Schedulers.boundedElastic()) + .flatMapIterable(Function.identity()); + } + + private List getFinalPathFromForwardAndBackward( + ForwardPage forwardPage, + BackwardPage backwardPage + ) { + var path = new ArrayList(); + + var forwardPages = new ArrayList(); + var curFwdPage = forwardPage; + while (curFwdPage != null) { + forwardPages.add(curFwdPage); + curFwdPage = curFwdPage.getParentPage(); + } + + Collections.reverse(forwardPages); + for (var fwdPg : forwardPages) { + path.add(fwdPg.getTitle()); + } + + var curBwdPage = backwardPage.getChildPage(); + while (curBwdPage != null) { + path.add(curBwdPage.getTitle()); + curBwdPage = curBwdPage.getChildPage(); + } + + return path; + } + + +}