diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000000000000000000000000000000000..8af972cded0d3e3ccb3c6e801150168bcc93150a --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +/gradlew text eol=lf +*.bat text eol=crlf +*.jar binary diff --git a/.gitignore b/.gitignore index 3ee9f36f53f97ee347cd95332ba4e5578c13215c..c2065bc26202b2d072aca3efc3d1c2efad3afcbf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,19 +1,37 @@ -pdfunctionlibrary.properties -pdfunctionlibrary.xml -# Ignore Gradle GUI config -gradle-app.setting +HELP.md +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ -# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) -!gradle-wrapper.jar +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ -# Cache of project -.gradletasknamecache +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ -.gradle/ -.idea/ -build/ -gradlew.bat -gradlew +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ -# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 -# gradle/wrapper/gradle-wrapper.properties +### VS Code ### +.vscode/ diff --git a/build.gradle b/build.gradle index ace3c10a97a9f7019a9ed9104044e2bef183c48f..9c28d0e8065c282e0b88e31adca88a159405ebd5 100644 --- a/build.gradle +++ b/build.gradle @@ -1,124 +1,114 @@ plugins { - id 'java' - id 'idea' + id 'java' + id 'idea' } -tasks.withType(JavaCompile) { - options.encoding = "UTF-8" +tasks.withType(JavaCompile).configureEach { + options.encoding = "UTF-8" } group 'fybug.nulll' -version = '0.0.2 expand 2' -sourceCompatibility = '14' -targetCompatibility = '14' +version = '0.0.2 expand 3' -configurations { - developmentOnly - runtimeClasspath { - extendsFrom developmentOnly - } - compileOnly { - extendsFrom annotationProcessor - } +java { + toolchain { + languageVersion = JavaLanguageVersion.of(23) + } } repositories { - mavenLocal() - mavenCentral() - maven { url 'https://repo.spring.io/milestone' } - maven { url 'https://repo.spring.io/snapshot' } - maven { url "https://maven.aliyun.com/repository/central" } - maven { url "https://maven.aliyun.com/repository/public" } - maven { url "https://maven.aliyun.com/repository/google" } - maven { url "https://maven.aliyun.com/repository/gradle-plugin" } - maven { url "https://maven.aliyun.com/repository/spring" } - maven { url "https://maven.aliyun.com/repository/spring-plugin" } - maven { url "https://maven.aliyun.com/repository/grails-core" } - maven { url "https://maven.aliyun.com/repository/apache-snapshots" } - maven { url "http://repo.spring.io/milestone" } + mavenLocal() + mavenCentral() + google() + maven { url 'https://maven.aliyun.com/repository/releases' } + maven { url "https://maven.aliyun.com/repository/jcenter" } + maven { url "https://maven.aliyun.com/repository/mapr-public" } + maven { url "https://maven.aliyun.com/repository/staging-alpha" } + maven { url "https://maven.aliyun.com/repository/central" } + maven { url "https://maven.aliyun.com/repository/public/" } + maven { url "https://maven.aliyun.com/repository/google" } + maven { url "https://maven.aliyun.com/repository/gradle-plugin" } + maven { url "https://maven.aliyun.com/repository/spring" } + maven { url "https://maven.aliyun.com/repository/spring-plugin" } + maven { url "https://maven.aliyun.com/repository/grails-core" } + maven { url "https://maven.aliyun.com/repository/snapshots" } + maven { url "https://maven.aliyun.com/repository/apache-snapshots" } + maven { url "https://maven.aliyun.com/repository/staging-alpha-group" } } dependencies { - implementation fileTree(dir: 'lib', includes: ['*.jar']) - compileClasspath "org.jetbrains:annotations:17.0.0" - compileClasspath "org.projectlombok:lombok:1.18.10" - annotationProcessor "org.projectlombok:lombok:1.18.10" + // 本地依赖 + implementation fileTree(dir: 'lib', includes: ['*.jar']) - testCompile "junit:junit:4.12" - testCompile "org.jetbrains:annotations:17.0.0" - testCompile "org.projectlombok:lombok:1.18.10" + // 注释包 + compileOnly "jakarta.validation:jakarta.validation-api:+" + compileOnly "jakarta.annotation:jakarta.annotation-api:+" + // lombok + compileOnly 'org.projectlombok:lombok:+' + annotationProcessor 'org.projectlombok:lombok:+' + + // 注释包 + testCompileOnly "jakarta.validation:jakarta.validation-api:+" + testCompileOnly "jakarta.annotation:jakarta.annotation-api:+" + // lombok + testCompileOnly "org.projectlombok:lombok:+" + testAnnotationProcessor "org.projectlombok:lombok:+" + testRuntimeOnly "org.junit.jupiter:junit-jupiter:5.12.0-RC2" +} + +test { + dependencies { + testImplementation "org.junit.jupiter:junit-jupiter:5.12.0-RC2" + } + useJUnitPlatform() } -task PDCache(type: Jar) { - destinationDirectory = file('jar') - manifest { - attributes( - 'Manifest-Version': '1.0', - 'Built-By': 'fybug/风雨bu改', - 'Created-By': 'IntelliJ IDEA' - ) - } - archiveFileName = 'PDCache.jar' - // 打包编译输出 - from sourceSets.main.output +/** 清单文件内容 */ +tasks.withType(Jar).configureEach { + destinationDirectory = file('jar') + manifest { + attributes('Manifest-Version': '1.0', + 'Built-By': 'fybug/风雨bu改', + 'Build-Jdk-Spec': 23, + 'Bundle-Description': '描述', + 'Bundle-Name': 'PDCache', + // 'Bundle-DocURL': 'https://apidoc.gitee.com/fybug/PDConcurrent/', + 'Bundle-Vendor': 'IntelliJ IDEA', + 'Bundle-Version': version, + 'Bundle-License': 'https://www.apache.org/licenses/LICENSE-2.0', + 'Created-By': 'Gradle 8.10.2') + } } -task PDCache_bin(type: Jar) { - destinationDirectory = file('jar') - manifest { - attributes( - 'Manifest-Version': '1.0', - 'Built-By': 'fybug/风雨bu改', - 'Created-By': 'IntelliJ IDEA' - ) - } - archiveFileName = 'PDCache_bin.jar' - // 打包编译输出 - from sourceSets.main.output - from { - // implementation 相关的引入解压并打包入新的jar中 - configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } - } +/** 编译包 */ +tasks.register('PDCache', Jar) { + archiveFileName = 'PDCache.jar' + archiveClassifier = '' + // 打包编译输出 + from sourceSets.main.output } -task PDCache_all(type: Jar) { - destinationDirectory = file('jar') - manifest { - attributes( - 'Manifest-Version': '1.0', - 'Built-By': 'fybug/风雨bu改', - 'Created-By': 'IntelliJ IDEA' - ) - } - archiveFileName = 'PDCache_all.jar' - // 打包编译输出 - from sourceSets.main.output - // 打包源码 - from sourceSets.main.allSource - from { - // implementation 相关的引入解压并打包入新的jar中 - configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } - } +tasks.register('PDCache_bin', Jar) { + archiveFileName = 'PDCache_bin.jar' + archiveClassifier = 'bin' + // 打包编译输出 + from sourceSets.main.output + from { + // implementation 相关的引入解压并打包入新的jar中 + configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } + } } -task PDCache_sources(type: Jar) { - destinationDirectory = file('jar') - manifest { - attributes( - 'Manifest-Version': '1.0', - 'Built-By': 'fybug/风雨bu改', - 'Created-By': 'IntelliJ IDEA' - ) - } - archiveFileName = 'PDCache_sources.jar' - // 打包源码 - from sourceSets.main.allSource +/** 源码包 */ +tasks.register('PDCache_sources', Jar) { + archiveFileName = 'PDCache_sources.jar' + archiveClassifier = 'sources' + // 打包源码 + from sourceSets.main.allSource } -task release { - dependsOn clean - dependsOn PDCache_all - dependsOn PDCache_bin - dependsOn PDCache - dependsOn PDCache_sources +tasks.register('release') { + dependsOn PDCache + dependsOn PDCache_bin + dependsOn PDCache_sources } \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..a4b76b9530d66f5e68d973ea569d8e19de379189 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 622ab64a3cb60378cd29384961554c0b032c9368..e0dfef4284c2074f9674dc5a45dd2f4334c247f3 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,8 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip +distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-8.10.2-bin.zip +#distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 0000000000000000000000000000000000000000..f5feea6d6b116baaca5a2642d4d9fa1f47d574a7 --- /dev/null +++ b/gradlew @@ -0,0 +1,252 @@ +#!/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. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# 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/HEAD/platforms/jvm/plugins-application/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 + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit + +# 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 + 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=SC2039,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=SC2039,SC3045 + 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 + + +# 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, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +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/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000000000000000000000000000000000000..27bf976f8e2ed20d0cc85746c8eabfc40d1765bd --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,94 @@ +@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 DocumentType 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 +@rem SPDX-License-Identifier: Apache-2.0 +@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=. +@rem This is normally unused +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. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +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/jar/PDCache.jar b/jar/PDCache.jar index cbd859023e8165ce953c6b433abdbf069ac57f82..fd6e964d816c534c2321828ced52b324a62fc889 100644 Binary files a/jar/PDCache.jar and b/jar/PDCache.jar differ diff --git a/jar/PDCache_all.jar b/jar/PDCache_all.jar deleted file mode 100644 index 8092be2ac1474a53130130270a51eb300485aa56..0000000000000000000000000000000000000000 Binary files a/jar/PDCache_all.jar and /dev/null differ diff --git a/jar/PDCache_bin.jar b/jar/PDCache_bin.jar index 8ccce784d2b471f99a44f6630019f89a39a64c36..32a9b6327b54e5af13603cace10111713aee5b19 100644 Binary files a/jar/PDCache_bin.jar and b/jar/PDCache_bin.jar differ diff --git a/jar/PDCache_sources.jar b/jar/PDCache_sources.jar index 9d50cc8e120481dddbc9ef154f0aa3b45cf5a39d..c5d6aae8ef82cb6c073d4ae33bbabb94c9851102 100644 Binary files a/jar/PDCache_sources.jar and b/jar/PDCache_sources.jar differ diff --git a/lib/PDConcurrent.jar b/lib/PDConcurrent.jar deleted file mode 100644 index 98103e5a6d9014ab63d80770d25070d74643595d..0000000000000000000000000000000000000000 Binary files a/lib/PDConcurrent.jar and /dev/null differ diff --git a/lib/PDConcurrent_bin.jar b/lib/PDConcurrent_bin.jar new file mode 100644 index 0000000000000000000000000000000000000000..7c201907b4d9571e7718389e537db8c357499f93 Binary files /dev/null and b/lib/PDConcurrent_bin.jar differ diff --git a/pom.xml b/pom.xml deleted file mode 100644 index f9c2bfb61f0454207c5a8530bfd0f0bf7887bedf..0000000000000000000000000000000000000000 --- a/pom.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - 4.0.0 - - fybug.nulll - PDCache - 0.0.2 expand 2 - - - - org.apache.maven.plugins - maven-javadoc-plugin - 3.0.0 - - -Xdoclint:none - - - - attach-javadocs - - jar - - - - - - - \ No newline at end of file diff --git a/src/main/java/fybug/nulll/pdcache/CacheGcThrea.java b/src/main/java/fybug/nulll/pdcache/CacheGcThrea.java index c7dfda0f9f39e758be0fc59dddfd505521e0218f..f437899fafc7becc6b86248f122b1acbadd73137 100644 --- a/src/main/java/fybug/nulll/pdcache/CacheGcThrea.java +++ b/src/main/java/fybug/nulll/pdcache/CacheGcThrea.java @@ -1,8 +1,7 @@ package fybug.nulll.pdcache; -import org.jetbrains.annotations.NotNull; - import java.lang.ref.Cleaner; +import jakarta.validation.constraints.NotNull; import lombok.experimental.UtilityClass; /** @@ -15,13 +14,13 @@ import lombok.experimental.UtilityClass; @UtilityClass public class CacheGcThrea { - /** - * 为指定对象绑定回收接口 - * - * @see Cleaner#register(Object, Runnable) - */ - @NotNull - public - Cleaner.Cleanable binClean(@NotNull Object obj, @NotNull Runnable run) - { return Cleaner.create().register(obj, run); } + /** + * 为指定对象绑定回收接口 + * + * @see Cleaner#register(Object, Runnable) + */ + @NotNull + public + Cleaner.Cleanable binClean(@NotNull Object obj, @NotNull Runnable run) + { return Cleaner.create().register(obj, run); } } \ No newline at end of file diff --git a/src/main/java/fybug/nulll/pdcache/CacheOb.java b/src/main/java/fybug/nulll/pdcache/CacheOb.java index 1d698ac44616fbe134ccbe809ee51a1376a5122a..68bb971a6d209bfd8f5195e86551d3e99ca76315 100644 --- a/src/main/java/fybug/nulll/pdcache/CacheOb.java +++ b/src/main/java/fybug/nulll/pdcache/CacheOb.java @@ -1,13 +1,12 @@ package fybug.nulll.pdcache; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - import java.lang.ref.Cleaner; import java.lang.ref.Reference; import java.lang.ref.SoftReference; import java.lang.ref.WeakReference; import fybug.nulll.pdconcurrent.SyLock; +import jakarta.annotation.Nullable; +import jakarta.validation.constraints.NotNull; /** *

数据缓存通用类.

@@ -21,182 +20,174 @@ import fybug.nulll.pdconcurrent.SyLock; */ public abstract class CacheOb { - /** 缓存引用类型 */ - protected final Class> refClass; - /** 缓存引用 */ - protected volatile Reference cache = new WeakReference<>(null); - - /** 数据回收接口 */ - protected volatile Cleaner.Cleanable cleanable = null; - - /** 并发管理 */ - protected final SyLock LOCK; - - //---------------------------------------------------------------------------------------------- - - /** 构造缓存,指定缓存方式 */ - protected - CacheOb(@NotNull Class refc) {this(refc, SyLock.newRWLock()); } - - /** 构造缓存,指定缓存方式和并发管理 */ - protected - CacheOb(@NotNull Class refc, @NotNull SyLock syLock) { - this.refClass = (Class>) refc; - LOCK = syLock; + /** 缓存引用类型 */ + protected final Class> refClass; + /** 缓存引用 */ + protected volatile Reference cache = new WeakReference<>(null); + + /** 数据回收接口 */ + protected volatile Cleaner.Cleanable cleanable = null; + + /** 并发管理 */ + protected final SyLock LOCK; + + /** 构造缓存,指定缓存方式 */ + protected + CacheOb(@NotNull Class refc) { this(refc, SyLock.newRWLock()); } + + /** 构造缓存,指定缓存方式和并发管理 */ + protected + CacheOb(@NotNull Class refc, @NotNull SyLock syLock) { + this.refClass = (Class>) refc; + LOCK = syLock; + } + + /** + * 获取缓存 + * + * @return 当前缓存的数据 + */ + @Nullable + protected + V getdata() throws Exception { + var ref = new Object() { + V item; + }; + + // 赋予强引用,防止进入回收队列 + LOCK.read(() -> ref.item = cache.get()); + + // 校验数据 + if ( ref.item == null ) { + var b = true; + /* 自旋,直到数据完整 */ + while( b ){ + b = LOCK.write(() -> { + /* 是否在释放 */ + if ( (ref.item = cache.get()) == null ) { + /* 是否释放完成 */ + if ( cleanable == null ) { + // 获取空数据处理 + ref.item = emptyData(); + // 完整空数据 + return false; + } + // 未清理完成 + return true; + } + // 数据完整 + return false; + }); + } } - //---------------------------------------------------------------------------------------------- - - /** - * 获取缓存 - * - * @return 当前缓存的数据 - */ - @Nullable - protected - V getdata() throws Exception { - var ref = new Object() { - V item; - }; - - // 赋予强引用,防止进入回收队列 - LOCK.read(() -> ref.item = cache.get()); - - // 校验数据 - if (ref.item == null) { - var b = true; - /* 自旋,直到数据完整 */ - while( b ){ - b = LOCK.trywrite(Exception.class, () -> { - /* 是否在释放 */ - if ((ref.item = cache.get()) == null) { - /* 是否释放完成 */ - if (cleanable == null) { - // 获取空数据处理 - ref.item = emptyData(); - // 完整空数据 - return false; - } - // 未清理完成 - return true; - } - // 数据完整 - return false; - }); - } + return ref.item; + } + + /** + * 无数据时的数据 + * + * @return 在没有缓存时返回的数据 + */ + @Nullable + protected abstract + V emptyData() throws Exception; + + /** + * 放入数据 + * + * @param v 数据 + */ + protected + void putdata(@Nullable V v) throws Exception { + var ref = new Object() { + V item; + }; + + var b = true; + while( b ) + b = LOCK.write(() -> { + /* 正在释放 */ + if ( (ref.item = cache.get()) == null && cleanable != null ) + // 等待释放完成 + return true; + + // 获取对象的回收方法 + if ( v instanceof CanClean ) { + var c = ((CanClean) v).getclean(); + // 注册回收方法 + cleanable = CacheGcThrea.binClean(v, () -> LOCK.write(() -> { + c.run(); + cleanable = null; + }, null, null)); } - return ref.item; - } + // 绑定缓存 + cache = refClass.getConstructor(Object.class).newInstance(v); + // 处理完成 + return false; + }); + } + + /** + * 移除缓存 + *

+ * 强制释放缓存内容
+ * 将缓存内容主动加入回收队列 + */ + public + void clear() { + var ref = new Object() { + V item; + }; + LOCK.write(() -> { + // 正在被回收 + if ( (ref.item = cache.get()) == null ) + return; + // 手动释放 + cache.enqueue(); + }, null, null); + } + + /** + *

{@link CacheOb} 子类通用构造工具.

+ *
    + *
  • 使用 {@link #refernce(Class)} 绑定缓存方式
  • + *
  • 使用 {@link #lockBy(SyLock)} 绑定并发管理
  • + *
  • 使用 {@link #build()} 进行构造
  • + *
+ * + * @version 0.0.1 + * @since CacheOb 0.0.1 + */ + @SuppressWarnings("unchecked") + protected static abstract + class Build> { + /** 缓存引用类型 */ + protected Class refernce = SoftReference.class; + /** 并发管理 */ + protected SyLock lockBy = SyLock.newRWLock(); - /** - * 无数据时的数据 - * - * @return 在没有缓存时返回的数据 - */ - @Nullable - protected abstract - V emptyData() throws Exception; - - //----------------------------------- - - /** - * 放入数据 - * - * @param v 数据 - */ - protected - void putdata(@Nullable V v) throws Exception { - var ref = new Object() { - V item; - }; - - var b = true; - while( b ) - b = LOCK.trywrite(Exception.class, () -> { - /* 正在释放 */ - if ((ref.item = cache.get()) == null && cleanable != null) - // 等待释放完成 - return true; - - // 获取对象的回收方法 - if (v instanceof CanClean) { - var c = ((CanClean) v).getclean(); - // 注册回收方法 - cleanable = CacheGcThrea.binClean(v, () -> LOCK.write(() -> { - c.run(); - cleanable = null; - })); - } - - // 绑定缓存 - cache = refClass.getConstructor(Object.class).newInstance(v); - // 处理完成 - return false; - }); - } + //------------------------------------------------------------------------------------------ - /** - * 移除缓存 - *

- * 强制释放缓存内容
- * 将缓存内容主动加入回收队列 - */ - public - void clear() { - var ref = new Object() { - V item; - }; - LOCK.write(() -> { - // 正在被回收 - if ((ref.item = cache.get()) == null) - return; - // 手动释放 - cache.enqueue(); - }); + /** 设置缓存引用类型 */ + @NotNull + public final + B refernce(Class refernce) { + this.refernce = refernce; + return (B) this; } - /*--------------------------------------------------------------------------------------------*/ - - /** - *

{@link CacheOb} 子类通用构造工具.

- *
    - *
  • 使用 {@link #refernce(Class)} 绑定缓存方式
  • - *
  • 使用 {@link #lockBy(SyLock)} 绑定并发管理
  • - *
  • 使用 {@link #build()} 进行构造
  • - *
- * - * @version 0.0.1 - * @since CacheOb 0.0.1 - */ - @SuppressWarnings( "unchecked" ) - protected static abstract - class Build> { - /** 缓存引用类型 */ - protected Class refernce = SoftReference.class; - /** 并发管理 */ - protected SyLock lockBy = SyLock.newRWLock(); - - //------------------------------------------------------------------------------------------ - - /** 设置缓存引用类型 */ - @NotNull - public final - B refernce(Class refernce) { - this.refernce = refernce; - return (B) this; - } - - /** 设置并发管理 */ - @NotNull - public final - B lockBy(@NotNull SyLock lockBy) { - this.lockBy = lockBy; - return (B) this; - } - - @NotNull - public abstract - CacheOb build(); + /** 设置并发管理 */ + @NotNull + public final + B lockBy(@NotNull SyLock lockBy) { + this.lockBy = lockBy; + return (B) this; } + + @NotNull + public abstract + CacheOb build(); + } } diff --git a/src/main/java/fybug/nulll/pdcache/CanClean.java b/src/main/java/fybug/nulll/pdcache/CanClean.java index 56264cc0c00f035061e519b372f553608f32dad4..fbdf6d257d4e2f53458b68dc7411bd87b3e5a033 100644 --- a/src/main/java/fybug/nulll/pdcache/CanClean.java +++ b/src/main/java/fybug/nulll/pdcache/CanClean.java @@ -1,8 +1,8 @@ package fybug.nulll.pdcache; -import org.jetbrains.annotations.NotNull; - import java.lang.ref.Cleaner.Cleanable; +import jakarta.validation.constraints.NotNull; + /** *

拥有清理回调的对象.

* @@ -13,8 +13,8 @@ import java.lang.ref.Cleaner.Cleanable; */ public interface CanClean { - /** 生成一个清理回调,在对象被回收的时候会调用该回调 */ - @NotNull - default - Runnable getclean() {return () -> {};} + /** 生成一个清理回调,在对象被回收的时候会调用该回调 */ + @NotNull + default + Runnable getclean() { return () -> {}; } } diff --git a/src/main/java/fybug/nulll/pdcache/MapCacheOb.java b/src/main/java/fybug/nulll/pdcache/MapCacheOb.java index 4312cf2d9d448f126c9910bc80b5c288c0b7eff8..8262322a92c568a58dbaeaa8b49cad931bd24d7f 100644 --- a/src/main/java/fybug/nulll/pdcache/MapCacheOb.java +++ b/src/main/java/fybug/nulll/pdcache/MapCacheOb.java @@ -1,7 +1,4 @@ package fybug.nulll.pdcache; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - import java.lang.ref.Cleaner; import java.lang.ref.Reference; import java.lang.ref.SoftReference; @@ -9,6 +6,8 @@ import java.util.HashMap; import java.util.Map; import fybug.nulll.pdconcurrent.SyLock; +import jakarta.annotation.Nullable; +import jakarta.validation.constraints.NotNull; /** *

映射缓存通用类.

@@ -23,240 +22,233 @@ import fybug.nulll.pdconcurrent.SyLock; */ public abstract class MapCacheOb { + /** 缓存引用类型 */ + protected final Class> refClass; + /** 数据缓存区 */ + protected final Map> map = new HashMap<>(); + + /** 回收接口存放区 */ + protected final Map cleanableMap = new HashMap<>(); + + /** 并发管理 */ + protected final SyLock LOCK; + + //---------------------------------------------------------------------------------------------- + + /** 构造缓存,指定缓存方式 */ + public + MapCacheOb(@NotNull Class refc) { this(refc, SyLock.newRWLock()); } + + /** 构造缓存,指定缓存方式和并发管理 */ + public + MapCacheOb(@NotNull Class refc, @NotNull SyLock syLock) { + refClass = (Class>) refc; + LOCK = syLock; + } + + //---------------------------------------------------------------------------------------------- + + /** + * 获取缓存数据 + * + * @param key 缓存的键 + * + * @return 缓存记录对象 + * + * @see Enty + */ + @NotNull + protected + MapCacheOb.Enty getdata(@NotNull K key) throws Exception { + // 缓存记录对象 + final var enty = new Enty(); + + // get ref + LOCK.read(() -> { + enty.ref = map.get(key); + // 获取内容 + if ( enty.ref == null ) + enty.val = null; + else + enty.val = enty.ref.get(); + }); + + /* 检查获取的数据 */ + if ( enty.val == null ) { + var b = true; + /* 自旋,直到数据完整 */ + while( b ){ + b = LOCK.write(() -> { + /* 当前是否正在释放 */ + if ( (enty.ref = map.get(key)) == null || (enty.val = enty.ref.get()) == null ) { + /* 扫尾接口是否运行完成 */ + if ( cleanableMap.get(key) == null ) { + // 空数据处理 + enty.val = emptyData(key); + enty.ref = map.get(key); + + // 被彻底释放,完整的空数据 + return false; + } + // 数据不完整,继续等待 + return true; + } else + // 数据完整 + return false; + }); + } + } + return enty; + } + + /** + * 无数据时的数据 + * + * @return 在没有缓存时返回的数据 + */ + @Nullable + protected abstract + V emptyData(@NotNull K key) throws Exception; + + /** + * 更新缓存内容 + * + * @param key 缓存键 + * @param v 缓存内容 + */ + protected + void putdata(@NotNull K key, @NotNull V v) throws Exception { + final var enty = new Enty(); + + /* 检查获取的数据 */ + var b = true; + /* 自旋,直到数据完整 */ + while( b ){ + b = LOCK.write(() -> { + /* 正在释放 */ + if ( ((enty.ref = map.get(key)) != null && (enty.val = enty.ref.get()) == null) && cleanableMap.get(key) != null ) + // 等待释放完成 + return true; + + /* 获取对象的回收方法 */ + Runnable clean; + if ( v instanceof CanClean ) + clean = ((CanClean) v).getclean(); + else + clean = null; + + /* 注册回收方法 */ + cleanableMap.put(key, CacheGcThrea.binClean(v, () -> LOCK.write(() -> { + if ( clean != null ) + clean.run(); + cleanableMap.remove(key); + map.remove(key); + }, null, null))); + + // 放入缓存 + map.put(key, refClass.getConstructor(Object.class).newInstance(v)); + // 处理完成 + return false; + }); + } + } + + /** + * 移除缓存 + *

+ * 强制释放缓存内容
+ * 将缓存内容主动加入回收队列 + * + * @param key 要释放的键 + * + * @return 释放的内容 + */ + @Nullable + protected + V removeData(@NotNull K key) { + final var cac = new Object() { + Reference ref; + V v; + }; + + return LOCK.write(() -> { + // 已在释放 + if ( (cac.ref = map.get(key)) == null || (cac.v = cac.ref.get()) == null ) + return null; + + // 手动释放 + cac.ref.enqueue(); + return cac.v; + }, null, null); + } + + /** 清空缓存数据 */ + public + void clear() { + // 释放 + LOCK.write(() -> { + map.values().forEach(v -> { + // 对象被释放 + if ( v == null || v.get() == null ) + return; + v.enqueue(); + }); + map.clear(); + }, null, null); + } + + /** + *

{@link MapCacheOb} 子类通用构造工具.

+ *
    + *
  • 使用 {@link #refernce(Class)} 绑定缓存方式
  • + *
  • 使用 {@link #lockBy(SyLock)} 绑定并发管理
  • + *
  • 使用 {@link #build()} 进行构造
  • + *
+ * + * @version 0.0.1 + * @since MapCacheOb 0.0.1 + */ + @SuppressWarnings("unchecked") + public static abstract + class Build> { /** 缓存引用类型 */ - protected final Class> refClass; - /** 数据缓存区 */ - protected final Map> map = new HashMap<>(); - - /** 回收接口存放区 */ - protected final Map cleanableMap = new HashMap<>(); - + protected Class refernce = SoftReference.class; /** 并发管理 */ - protected final SyLock LOCK; - - //---------------------------------------------------------------------------------------------- + protected SyLock lockBy = SyLock.newRWLock(); - /** 构造缓存,指定缓存方式 */ - public - MapCacheOb(@NotNull Class refc) { this(refc, SyLock.newRWLock()); } - - /** 构造缓存,指定缓存方式和并发管理 */ + /** 设置缓存引用类型 */ + @NotNull public - MapCacheOb(@NotNull Class refc, @NotNull SyLock syLock) { - refClass = (Class>) refc; - LOCK = syLock; + B refernce(Class refernce) { + this.refernce = refernce; + return (B) this; } - //---------------------------------------------------------------------------------------------- - - /** - * 获取缓存数据 - * - * @param key 缓存的键 - * - * @return 缓存记录对象 - * - * @see Enty - */ + /** 设置并发管理 */ @NotNull - protected - MapCacheOb.Enty getdata(@NotNull K key) throws Exception { - // 缓存记录对象 - final var enty = new Enty(); - - // get ref - LOCK.read(() -> { - enty.ref = map.get(key); - // 获取内容 - if (enty.ref == null) - enty.val = null; - else - enty.val = enty.ref.get(); - }); - - /* 检查获取的数据 */ - if (enty.val == null) { - var b = true; - /* 自旋,直到数据完整 */ - while( b ){ - b = LOCK.trywrite(Exception.class, () -> { - /* 当前是否正在释放 */ - if ((enty.ref = map.get(key)) == null || (enty.val = enty.ref.get()) == null) { - /* 扫尾接口是否运行完成 */ - if (cleanableMap.get(key) == null) { - // 空数据处理 - enty.val = emptyData(key); - enty.ref = map.get(key); - - // 被彻底释放,完整的空数据 - return false; - } - // 数据不完整,继续等待 - return true; - } else - // 数据完整 - return false; - }); - } - } - return enty; - } - - /** - * 无数据时的数据 - * - * @return 在没有缓存时返回的数据 - */ - @Nullable - protected abstract - V emptyData(@NotNull K key) throws Exception; - - //---------------------------------------------------------------------------------------------- - - /** - * 更新缓存内容 - * - * @param key 缓存键 - * @param v 缓存内容 - */ - protected - void putdata(@NotNull K key, @NotNull V v) throws Exception { - final var enty = new Enty(); - - /* 检查获取的数据 */ - var b = true; - /* 自旋,直到数据完整 */ - while( b ){ - b = LOCK.trywrite(Exception.class, () -> { - /* 正在释放 */ - if (((enty.ref = map.get(key)) != null && (enty.val = enty.ref.get()) == null) && - cleanableMap.get(key) != null) - // 等待释放完成 - return true; - - /* 获取对象的回收方法 */ - Runnable clean; - if (v instanceof CanClean) - clean = ((CanClean) v).getclean(); - else - clean = null; - - /* 注册回收方法 */ - cleanableMap.put(key, CacheGcThrea.binClean(v, () -> LOCK.write(() -> { - if (clean != null) - clean.run(); - cleanableMap.remove(key); - map.remove(key); - }))); - - // 放入缓存 - map.put(key, refClass.getConstructor(Object.class).newInstance(v)); - // 处理完成 - return false; - }); - } - } - - /** - * 移除缓存 - *

- * 强制释放缓存内容
- * 将缓存内容主动加入回收队列 - * - * @param key 要释放的键 - * - * @return 释放的内容 - */ - @Nullable - protected - V removeData(@NotNull K key) { - final var cac = new Object() { - Reference ref; - V v; - }; - - return LOCK.write(() -> { - // 已在释放 - if ((cac.ref = map.get(key)) == null || (cac.v = cac.ref.get()) == null) - return null; - - // 手动释放 - cac.ref.enqueue(); - return cac.v; - }); - } - - /** 清空缓存数据 */ public - void clear() { - // 释放 - LOCK.write(() -> { - map.values().forEach(v -> { - // 对象被释放 - if (v == null || v.get() == null) - return; - v.enqueue(); - }); - map.clear(); - }); - } - - /*--------------------------------------------------------------------------------------------*/ - - /** - *

{@link MapCacheOb} 子类通用构造工具.

- *
    - *
  • 使用 {@link #refernce(Class)} 绑定缓存方式
  • - *
  • 使用 {@link #lockBy(SyLock)} 绑定并发管理
  • - *
  • 使用 {@link #build()} 进行构造
  • - *
- * - * @version 0.0.1 - * @since MapCacheOb 0.0.1 - */ - @SuppressWarnings( "unchecked" ) - public static abstract - class Build> { - /** 缓存引用类型 */ - protected Class refernce = SoftReference.class; - /** 并发管理 */ - protected SyLock lockBy = SyLock.newRWLock(); - - /** 设置缓存引用类型 */ - @NotNull - public - B refernce(Class refernce) { - this.refernce = refernce; - return (B) this; - } - - /** 设置并发管理 */ - @NotNull - public - B lockBy(@NotNull SyLock lockBy) { - this.lockBy = lockBy; - return (B) this; - } - - @NotNull - public abstract - MapCacheOb build(); + B lockBy(@NotNull SyLock lockBy) { + this.lockBy = lockBy; + return (B) this; } - /*--------------------------------------------------------------------------------------------*/ - - /** - *

缓存记录类.

- * 记录缓存的引用对象 {@link #ref}
- * 记录缓存的内容 {@link #val} - * - * @author fybug - * @version 0.0.1 - * @since MapCacheOb 0.0.1 - */ - protected final - class Enty { - public volatile Reference ref; - public volatile V val; - } + @NotNull + public abstract + MapCacheOb build(); + } + + /** + *

缓存记录类.

+ * 记录缓存的引用对象 {@link #ref}
+ * 记录缓存的内容 {@link #val} + * + * @author fybug + * @version 0.0.1 + * @since MapCacheOb 0.0.1 + */ + protected final + class Enty { + public volatile Reference ref; + public volatile V val; + } } diff --git a/src/main/java/fybug/nulll/pdcache/MemoryCache.java b/src/main/java/fybug/nulll/pdcache/MemoryCache.java index 6d12c1cff87ecafb8f070979b21667eef4e34966..9a82380af2e26d4c52c47041f445784c9d4009fd 100644 --- a/src/main/java/fybug/nulll/pdcache/MemoryCache.java +++ b/src/main/java/fybug/nulll/pdcache/MemoryCache.java @@ -1,11 +1,10 @@ package fybug.nulll.pdcache; -import org.jetbrains.annotations.NotNull; - import java.io.Closeable; import java.lang.ref.Reference; import fybug.nulll.pdconcurrent.SyLock; import fybug.nulll.pdconcurrent.fun.tryConsumer; +import jakarta.validation.constraints.NotNull; /** *

作用于内存中的数据缓存.

@@ -19,46 +18,42 @@ import fybug.nulll.pdconcurrent.fun.tryConsumer; public abstract class MemoryCache extends CacheOb implements Closeable { - /** 构造缓存,指定缓存方式 */ - protected - MemoryCache(@NotNull Class refc) { super(refc); } - - /** 构造缓存,指定缓存方式和并发管理 */ - protected - MemoryCache(@NotNull Class refc, @NotNull SyLock syLock) - { super(refc, syLock); } - - //---------------------------------------------------------------------------------------------- - - /** - * 使用缓存的内容运行 - *

- * 可以避免没有给予缓存对象强引用而导致缓存丢失的情况 - * - * @param run 使用缓存的回调 - * - * @return V - * - * @see #get() - */ - public - V get(@NotNull tryConsumer run) throws Exception { - var i = get(); - run.accept(i); - return i; - } - - /** - * 获取缓存数据 - * - * @return 缓存数据 - */ - public - V get() throws Exception { return getdata(); } - - //---------------------------------------------------------------------------------------------- - - @Override - public - void close() { clear(); } + /** 构造缓存,指定缓存方式 */ + protected + MemoryCache(@NotNull Class refc) { super(refc); } + + /** 构造缓存,指定缓存方式和并发管理 */ + protected + MemoryCache(@NotNull Class refc, @NotNull SyLock syLock) + { super(refc, syLock); } + + /** + * 使用缓存的内容运行 + *

+ * 可以避免没有给予缓存对象强引用而导致缓存丢失的情况 + * + * @param run 使用缓存的回调 + * + * @return V + * + * @see #get() + */ + public + V get(@NotNull tryConsumer run) throws Exception { + var i = get(); + run.accept(i); + return i; + } + + /** + * 获取缓存数据 + * + * @return 缓存数据 + */ + public + V get() throws Exception { return getdata(); } + + @Override + public + void close() { clear(); } } diff --git a/src/main/java/fybug/nulll/pdcache/MemoryMapCache.java b/src/main/java/fybug/nulll/pdcache/MemoryMapCache.java index 2ab1d2bea32198daf5f87393f4962f34324312a6..644ee9c6fe821d19909751b5bf89b65f4ab2b5a1 100644 --- a/src/main/java/fybug/nulll/pdcache/MemoryMapCache.java +++ b/src/main/java/fybug/nulll/pdcache/MemoryMapCache.java @@ -1,12 +1,11 @@ package fybug.nulll.pdcache; -import org.jetbrains.annotations.NotNull; - import java.io.Closeable; import java.lang.ref.Reference; +import java.util.function.BiConsumer; import fybug.nulll.pdcache.err.CacheError; import fybug.nulll.pdconcurrent.SyLock; -import fybug.nulll.pdconcurrent.fun.tryBiConsumer; +import jakarta.validation.constraints.NotNull; import lombok.Getter; /** @@ -22,73 +21,66 @@ import lombok.Getter; */ public abstract class MemoryMapCache extends MapCacheOb implements Closeable { - public - MemoryMapCache(@NotNull Class refc) { super(refc); } - - public - MemoryMapCache(@NotNull Class refc, @NotNull SyLock syLock) - { super(refc, syLock); } - - //---------------------------------------------------------------------------------------------- - - /** - * 获取缓存数据 - * - * @param key 缓存的键 - * - * @return 缓存数据 - */ - public - V get(@NotNull K key) throws Exception, CacheError { - if (isClose()) - throw new CacheError(); - return getdata(key).val; - } + public + MemoryMapCache(@NotNull Class refc) { super(refc); } - /** - * 使用缓存的内容运行 - *

- * 可以避免没有给予缓存对象强引用而导致缓存丢失的情况 - * - * @param key 缓存的键 - * @param run 使用缓存的回调,传入 param key 和 {@link #get(K)} - * - * @return 缓存数据 - * - * @see #get(K) - */ - public - V get(@NotNull K key, @NotNull tryBiConsumer run) throws Exception, CacheError - { - var cache = get(key); - run.accept(key, cache); - return cache; - } + public + MemoryMapCache(@NotNull Class refc, @NotNull SyLock syLock) + { super(refc, syLock); } - //---------------------------------------------------------------------------------------------- + /** + * 获取缓存数据 + * + * @param key 缓存的键 + * + * @return 缓存数据 + */ + public + V get(@NotNull K key) throws Exception, CacheError { + if ( isClose() ) + throw new CacheError(); + return getdata(key).val; + } - /** - * 移除缓存 - *

- * 强制释放缓存内容
- * 将缓存内容主动加入回收队列 - * - * @param key 要释放的键 - */ - public - void remove(@NotNull K key) { removeData(key); } + /** + * 使用缓存的内容运行 + *

+ * 可以避免没有给予缓存对象强引用而导致缓存丢失的情况 + * + * @param key 缓存的键 + * @param run 使用缓存的回调,传入 param key 和 {@link #get(K)} + * + * @return 缓存数据 + * + * @see #get(K) + */ + public + V get(@NotNull K key, @NotNull BiConsumer run) throws Exception, CacheError { + var cache = get(key); + run.accept(key, cache); + return cache; + } - //---------------------------------------------------------------------------------------------- + /** + * 移除缓存 + *

+ * 强制释放缓存内容
+ * 将缓存内容主动加入回收队列 + * + * @param key 要释放的键 + */ + public + void remove(@NotNull K key) { removeData(key); } - // 是否被关闭 - @Getter private volatile boolean isClose = false; + // 是否被关闭 + @Getter private volatile boolean isClose = false; - @Override - public - void close() { - if (isClose()) - return; - isClose = true; - clear(); - } + @Override + public + void close() { + if ( isClose() ) + return; + isClose = true; + clear(); + } } diff --git a/src/main/java/fybug/nulll/pdcache/PDCache.java b/src/main/java/fybug/nulll/pdcache/PDCache.java index ddcfac58525a1d33eefc4b1f81e23b175b1fa894..6e7af5a895413ae5c997c343240254cabb184c9b 100644 --- a/src/main/java/fybug/nulll/pdcache/PDCache.java +++ b/src/main/java/fybug/nulll/pdcache/PDCache.java @@ -1,11 +1,10 @@ package fybug.nulll.pdcache; -import org.jetbrains.annotations.NotNull; - import fybug.nulll.pdcache.memory.Cache; import fybug.nulll.pdcache.memory.MapCache; import fybug.nulll.pdcache.memory.TimeMapCache; import fybug.nulll.pdcache.supplier.SCache; import fybug.nulll.pdcache.supplier.SMapCache; +import jakarta.validation.constraints.NotNull; import lombok.experimental.UtilityClass; /** @@ -20,75 +19,75 @@ import lombok.experimental.UtilityClass; @UtilityClass public class PDCache { - /** - * 缓存在内存中的单个数据缓存 - * - * @param vClass 数据类型 - * - * @return CacheBuild - * - * @see Cache - */ - @NotNull - public - Cache.Build Cache(Class vClass) { return Cache.build(vClass); } + /** + * 缓存在内存中的单个数据缓存 + * + * @param vClass 数据类型 + * + * @return CacheBuild + * + * @see Cache + */ + @NotNull + public + Cache.Build Cache(Class vClass) { return Cache.build(vClass); } - /** - * 缓存在内存中的自填充单个数据缓存 - * - * @param vClass 数据类型 - * - * @return SCacheBuild - * - * @see SCache - */ - @NotNull - public - SCache.Build SCache(Class vClass) { return SCache.build(vClass); } + /** + * 缓存在内存中的自填充单个数据缓存 + * + * @param vClass 数据类型 + * + * @return SCacheBuild + * + * @see SCache + */ + @NotNull + public + SCache.Build SCache(Class vClass) { return SCache.build(vClass); } - /** - * 缓存在内存中的映射数据缓存 - * - * @param kClass 键的类型 - * @param vClass 数据类型 - * - * @return MapCacheBuild - * - * @see MapCache - */ - @NotNull - public - MapCache.Build MapCache(Class kClass, Class vClass) - { return MapCache.build(kClass, vClass); } + /** + * 缓存在内存中的映射数据缓存 + * + * @param kClass 键的类型 + * @param vClass 数据类型 + * + * @return MapCacheBuild + * + * @see MapCache + */ + @NotNull + public + MapCache.Build MapCache(Class kClass, Class vClass) + { return MapCache.build(kClass, vClass); } - /** - * 缓存在内存中的自填充映射数据缓存 - * - * @param kClass 键的类型 - * @param vClass 数据类型 - * - * @return SMapCacheBuild - * - * @see SMapCache - */ - @NotNull - public - SMapCache.Build SMapCache(Class kClass, Class vClass) - { return SMapCache.build(kClass, vClass); } + /** + * 缓存在内存中的自填充映射数据缓存 + * + * @param kClass 键的类型 + * @param vClass 数据类型 + * + * @return SMapCacheBuild + * + * @see SMapCache + */ + @NotNull + public + SMapCache.Build SMapCache(Class kClass, Class vClass) + { return SMapCache.build(kClass, vClass); } - /** - * 缓存在内存中依靠时间管理的映射数据缓存 - * - * @param kClass 键的类型 - * @param vClass 数据类型 - * - * @return TimeMapCache - * - * @see TimeMapCache - * @since PDCache 0.0.2 - */ - @NotNull - public - TimeMapCache.Build TimeMapCache(Class kClass, Class vClass) - { return TimeMapCache.build(kClass, vClass); } + /** + * 缓存在内存中依靠时间管理的映射数据缓存 + * + * @param kClass 键的类型 + * @param vClass 数据类型 + * + * @return TimeMapCache + * + * @see TimeMapCache + * @since PDCache 0.0.2 + */ + @NotNull + public + TimeMapCache.Build TimeMapCache(Class kClass, Class vClass) + { return TimeMapCache.build(kClass, vClass); } } diff --git a/src/main/java/fybug/nulll/pdcache/err/CacheError.java b/src/main/java/fybug/nulll/pdcache/err/CacheError.java index f1131da5d9297bb77b3a940eda8f30a8a0c7e448..ffcb4e2ec5ac8ea13cf46625d356163b8be39bb3 100644 --- a/src/main/java/fybug/nulll/pdcache/err/CacheError.java +++ b/src/main/java/fybug/nulll/pdcache/err/CacheError.java @@ -7,4 +7,4 @@ package fybug.nulll.pdcache.err; * @version 0.0.1 */ public -class CacheError extends Exception {} +class CacheError extends RuntimeException {} diff --git a/src/main/java/fybug/nulll/pdcache/memory/Cache.java b/src/main/java/fybug/nulll/pdcache/memory/Cache.java index 81ca9c7b50d689c734a662529a4fef60e37e3125..e691ce6321d94301c62caf3659785d21dd8186f8 100644 --- a/src/main/java/fybug/nulll/pdcache/memory/Cache.java +++ b/src/main/java/fybug/nulll/pdcache/memory/Cache.java @@ -1,13 +1,12 @@ package fybug.nulll.pdcache.memory; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - import java.lang.ref.Reference; import fybug.nulll.pdcache.CacheOb; import fybug.nulll.pdcache.MemoryCache; import fybug.nulll.pdconcurrent.SyLock; import fybug.nulll.pdconcurrent.fun.tryConsumer; +import jakarta.annotation.Nullable; +import jakarta.validation.constraints.NotNull; /** *

数据缓存工具.

@@ -63,76 +62,70 @@ import fybug.nulll.pdconcurrent.fun.tryConsumer; public class Cache extends MemoryCache { - /** 构造缓存,指定缓存方式 */ - public - Cache(@NotNull Class refc) {super(refc); } + /** 构造缓存,指定缓存方式 */ + public + Cache(@NotNull Class refc) { super(refc); } - /** 构造缓存,指定缓存方式和并发管理 */ - public - Cache(@NotNull Class refc, @NotNull SyLock syLock) { super(refc, syLock); } + /** 构造缓存,指定缓存方式和并发管理 */ + public + Cache(@NotNull Class refc, @NotNull SyLock syLock) { super(refc, syLock); } - //---------------------------------------------------------------------------------------------- + @Nullable + @Override + public + V get(@NotNull tryConsumer run) throws Exception + { return super.get(run); } - @Nullable - @Override - public - V get(@NotNull tryConsumer<@Nullable V, Exception> run) throws Exception - { return super.get(run); } + @Nullable + @Override + public + V get() throws Exception { return super.get(); } - @Nullable - @Override - public - V get() throws Exception { return super.get(); } + @Override + protected @Nullable + V emptyData() + { return null; } - @Override - protected @Nullable - V emptyData() - { return null; } + /** + * 放入新的缓存 + * + * @param v 缓存的数据 + * + * @return this + */ + @NotNull + public + Cache set(@NotNull V v) throws Exception { + putdata(v); + return this; + } - //----------------------------------- + /** + * 获取缓存构造工具 + * + * @param 缓存内容的类型 + * + * @return 构造工具 + */ + @NotNull + public static + Build build(Class vc) { return new Build<>(); } - /** - * 放入新的缓存 - * - * @param v 缓存的数据 - * - * @return this - */ + /** + *

{@link Cache} 构造工具.

+ *
    + *
  • 使用 {@link #refernce(Class)} 绑定缓存方式
  • + *
  • 使用 {@link #lockBy(SyLock)} 绑定并发管理
  • + *
  • 使用 {@link #build()} 进行构造
  • + *
+ * + * @version 0.0.1 + * @since Cache 0.0.1 + */ + public final static + class Build extends CacheOb.Build> { @NotNull public - Cache set(@NotNull V v) throws Exception { - putdata(v); - return this; - } - - /*--------------------------------------------------------------------------------------------*/ - - /** - * 获取缓存构造工具 - * - * @param 缓存内容的类型 - * - * @return 构造工具 - */ - @NotNull - public static - Build build(Class vc) {return new Build<>();} - - /** - *

{@link Cache} 构造工具.

- *
    - *
  • 使用 {@link #refernce(Class)} 绑定缓存方式
  • - *
  • 使用 {@link #lockBy(SyLock)} 绑定并发管理
  • - *
  • 使用 {@link #build()} 进行构造
  • - *
- * - * @version 0.0.1 - * @since Cache 0.0.1 - */ - public final static - class Build extends CacheOb.Build> { - @NotNull - public - Cache build() { return new Cache<>(refernce, lockBy); } - } + Cache build() { return new Cache<>(refernce, lockBy); } + } } diff --git a/src/main/java/fybug/nulll/pdcache/memory/MapCache.java b/src/main/java/fybug/nulll/pdcache/memory/MapCache.java index c80cbcb99ce661f50e636b1a1ed606174b98da45..423d9757c075f9a5bed4618532ecb1767fa505dc 100644 --- a/src/main/java/fybug/nulll/pdcache/memory/MapCache.java +++ b/src/main/java/fybug/nulll/pdcache/memory/MapCache.java @@ -1,14 +1,13 @@ package fybug.nulll.pdcache.memory; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - import java.lang.ref.Reference; +import java.util.function.BiConsumer; import fybug.nulll.pdcache.MapCacheOb; import fybug.nulll.pdcache.MemoryMapCache; import fybug.nulll.pdcache.err.CacheError; import fybug.nulll.pdconcurrent.SyLock; -import fybug.nulll.pdconcurrent.fun.tryBiConsumer; +import jakarta.annotation.Nullable; +import jakarta.validation.constraints.NotNull; /** *

映射缓存.

@@ -66,87 +65,81 @@ import fybug.nulll.pdconcurrent.fun.tryBiConsumer; public class MapCache extends MemoryMapCache { - /** 构造缓存,指定缓存方式 */ - public - MapCache(@NotNull Class refc) { super(refc); } + /** 构造缓存,指定缓存方式 */ + public + MapCache(@NotNull Class refc) { super(refc); } - /** 构造缓存,指定缓存方式和并发管理 */ - public - MapCache(@NotNull Class refc, @NotNull SyLock syLock) - { super(refc, syLock); } + /** 构造缓存,指定缓存方式和并发管理 */ + public + MapCache(@NotNull Class refc, @NotNull SyLock syLock) + { super(refc, syLock); } - //---------------------------------------------------------------------------------------------- + /** + * 获取缓存数据 + * + * @param key 缓存的键 + * + * @return 缓存数据 + */ + @Override + @Nullable + public + V get(@NotNull K key) throws Exception, CacheError { return super.get(key); } - /** - * 获取缓存数据 - * - * @param key 缓存的键 - * - * @return 缓存数据 - */ - @Override - @Nullable - public - V get(@NotNull K key) throws Exception, CacheError { return super.get(key); } + @Override + @Nullable + public + V get(@NotNull K key, @NotNull BiConsumer run) throws Exception, CacheError + { return super.get(key, run); } - @Override - @Nullable - public - V get(@NotNull K key, @NotNull tryBiConsumer run) throws Exception, CacheError - { return super.get(key, run); } + /** + * 放入新的缓存 + * + * @param key 缓存的键 + * @param val 缓存的数据 + * + * @return this + */ + @NotNull + public + MapCache put(@NotNull K key, @NotNull V val) throws Exception, CacheError { + if ( isClose() ) + throw new CacheError(); + putdata(key, val); + return this; + } - //-------------------------------- + @Nullable + protected + V emptyData(@NotNull K key) { return null; } - /** - * 放入新的缓存 - * - * @param key 缓存的键 - * @param val 缓存的数据 - * - * @return this - */ - @NotNull - public - MapCache put(@NotNull K key, @NotNull V val) throws Exception, CacheError { - if (isClose()) - throw new CacheError(); - putdata(key, val); - return this; - } - - @Nullable - protected - V emptyData(@NotNull K key) { return null; } - - /*--------------------------------------------------------------------------------------------*/ + /** + * 获取缓存构造工具 + * + * @param 键的类型 + * @param 缓存内容的类型 + * + * @return 构造工具 + */ + @NotNull + public static + Build build(Class kc, Class vc) { return new Build<>(); } - /** - * 获取缓存构造工具 - * - * @param 键的类型 - * @param 缓存内容的类型 - * - * @return 构造工具 - */ + /** + *

{@link MapCache} 构造工具.

+ *
    + *
  • 使用 {@link #refernce(Class)} 绑定缓存方式
  • + *
  • 使用 {@link #lockBy(SyLock)} 绑定并发管理
  • + *
  • 使用 {@link #build()} 进行构造
  • + *
+ * + * @version 0.0.1 + * @since MapCache 0.0.1 + */ + public static final + class Build extends MapCacheOb.Build> { @NotNull - public static - Build build(Class kc, Class vc) {return new Build<>();} - - /** - *

{@link MapCache} 构造工具.

- *
    - *
  • 使用 {@link #refernce(Class)} 绑定缓存方式
  • - *
  • 使用 {@link #lockBy(SyLock)} 绑定并发管理
  • - *
  • 使用 {@link #build()} 进行构造
  • - *
- * - * @version 0.0.1 - * @since MapCache 0.0.1 - */ - public static final - class Build extends MapCacheOb.Build> { - @NotNull - public - MapCache build() { return new MapCache<>(refernce, lockBy); } - } + public + MapCache build() { return new MapCache<>(refernce, lockBy); } + } } diff --git a/src/main/java/fybug/nulll/pdcache/memory/TimeMapCache.java b/src/main/java/fybug/nulll/pdcache/memory/TimeMapCache.java index 5e289747907ad9bf6817a1f6056d51cfdad8b18e..38e3a9c7a4e1387ae397ef507fb1db84d36b21c6 100644 --- a/src/main/java/fybug/nulll/pdcache/memory/TimeMapCache.java +++ b/src/main/java/fybug/nulll/pdcache/memory/TimeMapCache.java @@ -1,7 +1,4 @@ package fybug.nulll.pdcache.memory; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; @@ -12,8 +9,11 @@ import java.util.concurrent.Executors; import java.util.function.Consumer; import java.util.function.Supplier; -import fybug.nulll.pdconcurrent.ObjLock; import fybug.nulll.pdconcurrent.SyLock; +import fybug.nulll.pdconcurrent.fun.trySupplier; +import fybug.nulll.pdconcurrent.lock.ObjLock; +import jakarta.annotation.Nullable; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NonNull; @@ -50,378 +50,367 @@ import lombok.val; */ public class TimeMapCache { - /** 数据缓存区 */ - protected final Map> map = new LinkedHashMap<>(); - /** 并发管理 */ - protected final SyLock LOCK; - - /** 数据过期时间(毫秒) */ - @Setter protected volatile long dataTime; - - /** 定时器 */ - @Nullable protected final Timer timerRun; - /** 从尾部扫描的数量 */ - @Setter protected volatile int scarrenNum; - - /** - * 回收事件执行线程池 - * - * @since 0.0.2 - */ - @NonNull - @Setter - @Getter - protected ExecutorService GcThread = Executors.newCachedThreadPool(); - - //---------------------------------------------------------------------------------------------- - - /** 构造缓存,使用默认参数 */ - public - TimeMapCache() { this(SyLock.newObjLock()); } - - /** 构造缓存,指定并发管理 */ - public - TimeMapCache(@NotNull SyLock syLock) { this(syLock, 24 * 60 * 60000); } - - /** 构造缓存,指定并发管理和默认过期时间 */ - public - TimeMapCache(@NotNull SyLock syLock, long datatime) { this(syLock, datatime, 5 * 60000); } - - /** - * 构造缓存,指定参数 - * - * @param syLock 并发管理 - * @param datatime 默认数据过期时间 - * @param scarrentime 检查线程扫描间隔,为 0 则不运行线程检查 - */ + /** 数据缓存区 */ + protected final Map> map = new LinkedHashMap<>(); + /** 并发管理 */ + protected final SyLock LOCK; + + /** 数据过期时间(毫秒) */ + @Setter protected volatile long dataTime; + + /** 定时器 */ + @Nullable protected final Timer timerRun; + /** 从尾部扫描的数量 */ + @Setter protected volatile int scarrenNum; + + /** + * 回收事件执行线程池 + * + * @since 0.0.2 + */ + @NonNull @Setter @Getter protected ExecutorService GcThread = Executors.newCachedThreadPool(); + + /** 构造缓存,使用默认参数 */ + public + TimeMapCache() { this(SyLock.newObjLock()); } + + /** 构造缓存,指定并发管理 */ + public + TimeMapCache(@NotNull SyLock syLock) { this(syLock, 24 * 60 * 60000); } + + /** 构造缓存,指定并发管理和默认过期时间 */ + public + TimeMapCache(@NotNull SyLock syLock, long datatime) { this(syLock, datatime, 5 * 60000); } + + /** + * 构造缓存,指定参数 + * + * @param syLock 并发管理 + * @param datatime 默认数据过期时间 + * @param scarrentime 检查线程扫描间隔,为 0 则不运行线程检查 + */ + public + TimeMapCache(@NotNull SyLock syLock, long datatime, long scarrentime) { + LOCK = syLock; + dataTime = datatime; + scarrenNum = 20; + + // 是否运行线程检查 + if ( scarrentime > 0 ) { + timerRun = new Timer(); + timerRun.schedule(new TimeTask(), 0, scarrentime); + } else + timerRun = null; + } + + /** + * 缓存检查任务 + * + * @author fybug + * @version 0.0.2 + * @since TimeMapCache 0.0.1 + */ + protected final + class TimeTask extends TimerTask { + @Override public - TimeMapCache(@NotNull SyLock syLock, long datatime, long scarrentime) { - LOCK = syLock; - dataTime = datatime; - scarrenNum = 20; - - // 是否运行线程检查 - if (scarrentime > 0) { - timerRun = new Timer(); - timerRun.schedule(new TimeTask(), 0, scarrentime); - } else - timerRun = null; - } - - /** - * 缓存检查任务 - * - * @author fybug - * @version 0.0.2 - * @since TimeMapCache 0.0.1 - */ - protected final - class TimeTask extends TimerTask { - @Override - public - void run() { - LOCK.write(() -> { - var now = System.currentTimeMillis(); - var i = 0; - var iter = map.entrySet().iterator(); - // 检查 - while( iter.hasNext() && i++ < scarrenNum ) - CheckVal(iter, now); - }); - } + void run() { + LOCK.write(() -> { + var now = System.currentTimeMillis(); + var i = 0; + var iter = map.entrySet().iterator(); + // 检查 + while( iter.hasNext() && i++ < scarrenNum ) + CheckVal(iter, now); + }, null, null); } - - /*--------------------------------------------------------------------------------------------*/ - - /** - * 放入数据 - * - * @param k 数据的键 - * @param v 数据内容 - * - * @see #putData(Object, Object, long) - */ - public - void putData(@NotNull K k, V v) { this.putData(k, v, dataTime); } - - /** - * 放入数据 - * - * @param k 数据的键 - * @param v 数据内容 - * @param datatime 数据的过期时间,相对于当前 - */ - public - void putData(@NotNull K k, @Nullable V v, long datatime) - { putData(k, v, datatime, null); } - - /** - * 放入数据 - * - * @param k 数据的键 - * @param v 数据内容 - * @param datatime 数据的过期时间,相对于当前 - * @param endrun 数据被回收事件回调,接口传入当前数据,为空则不触发 - * - * @since 0.0.2 - */ - public - void putData(@NotNull K k, @Nullable V v, long datatime, @Nullable Consumer endrun) - { LOCK.write(() -> map.put(k, new Enty<>(System.currentTimeMillis() + datatime, v, endrun))); } - - //------------------------------------- - - /** - * 移除数据 - * - * @param k 数据的键 - */ - public - void removeData(@NotNull K k) { LOCK.write(() -> GcVal(map.remove(k))); } - - /** - * 清除所有数据 - *

- * 不会触发回收事件 - */ - public - void clear() { LOCK.write(map::clear); } - - //------------------------------------- - - /** - * 使用数据 - *

- * 使用读锁进行 - * - * @param k 数据的键 - * - * @return 返回之前保存的数据,如果数据过期返回 null - * - * @see #getData(Object, long) - */ - @Nullable - public - V getData(@NotNull K k) { return getData(k, 0); } - - /** - * 使用数据 - *

- * 如果刷新时间为 0,则使用 {@link SyLock#read(Supplier)} 读锁进行
- * 如果需要刷新数据存活时间,则使用 {@link SyLock#write(Supplier)} 写锁进行 - * - * @param k 数据的键 - * @param newDatatime 数据的新存活时间,从现在开始记录 - * - * @return 返回之前保存的数据,如果数据过期返回 null - * - * @since TimeMapCache v0.0.3 - */ - @Nullable - public - V getData(@NotNull K k, long newDatatime) { - // 运行函数 - Supplier r = () -> { - if (check(k)) { - var v = map.remove(k); - - // 刷新时间 - if (newDatatime > 0) - v.setMaxtime(System.currentTimeMillis() + newDatatime); - - map.put(k, v); - return v.val; - } - GcVal(map.remove(k)); - return null; - }; - - // 刷新时间用写锁,不刷新用读锁 - if (newDatatime <= 0) - return LOCK.read(r); - else - return LOCK.write(r); + } + + /** + * 放入数据 + * + * @param k 数据的键 + * @param v 数据内容 + * + * @see #putData(Object, Object, long) + */ + public + void putData(@NotNull K k, V v) { this.putData(k, v, dataTime); } + + /** + * 放入数据 + * + * @param k 数据的键 + * @param v 数据内容 + * @param datatime 数据的过期时间,相对于当前 + */ + public + void putData(@NotNull K k, @Nullable V v, long datatime) + { putData(k, v, datatime, null); } + + /** + * 放入数据 + * + * @param k 数据的键 + * @param v 数据内容 + * @param datatime 数据的过期时间,相对于当前 + * @param endrun 数据被回收事件回调,接口传入当前数据,为空则不触发 + * + * @since 0.0.2 + */ + public + void putData(@NotNull K k, @Nullable V v, long datatime, @Nullable Consumer endrun) { + LOCK.write(() -> { + map.put(k, new Enty<>(System.currentTimeMillis() + datatime, v, endrun)); + }, null, null); + } + + /** + * 移除数据 + * + * @param k 数据的键 + */ + public + void removeData(@NotNull K k) { LOCK.write(() -> GcVal(map.remove(k)), null, null); } + + /** + * 清除所有数据 + *

+ * 不会触发回收事件 + */ + public + void clear() { LOCK.write(map::clear, null, null); } + + /** + * 使用数据 + *

+ * 使用读锁进行 + * + * @param k 数据的键 + * + * @return 返回之前保存的数据,如果数据过期返回 null + * + * @see #getData(Object, long) + */ + @Nullable + public + V getData(@NotNull K k) { return getData(k, 0); } + + /** + * 使用数据 + *

+ * 如果刷新时间为 0,则使用 {@link SyLock#read(Supplier)} 读锁进行
+ * 如果需要刷新数据存活时间,则使用 {@link SyLock#write(Supplier)} 写锁进行 + * + * @param k 数据的键 + * @param newDatatime 数据的新存活时间,从现在开始记录 + * + * @return 返回之前保存的数据,如果数据过期返回 null + * + * @since TimeMapCache v0.0.3 + */ + @Nullable + public + V getData(@NotNull K k, long newDatatime) { + // 运行函数 + trySupplier r = () -> { + if ( check(k) ) { + var v = map.remove(k); + + // 刷新时间 + if ( newDatatime > 0 ) + v.setMaxtime(System.currentTimeMillis() + newDatatime); + + map.put(k, v); + return v.val; + } + GcVal(map.remove(k)); + return null; + }; + + // 刷新时间用写锁,不刷新用读锁 + if ( newDatatime <= 0 ) + return LOCK.read(r, null, null); + else + return LOCK.write(r, null, null); + } + + /** + * 检查数据是否可用 + * + * @param k 数据的键 + * + * @return 可用为 true + */ + public + boolean checkData(@NotNull K k) { + return LOCK.read(() -> { + return check(k); + }, null, null); + } + + /** 检查数据是否可用 */ + protected + boolean check(@NotNull K k) + { return map.getOrDefault(k, new Enty<>(0, null, null)).maxtime > System.currentTimeMillis(); } + + /** + * 获取数据剩余的存活时间 + * + * @param k 数据的键 + * + * @return 剩余时间(毫秒),过期为 0 + */ + public + long dataHasTime(@NotNull K k) { + return LOCK.read(() -> { + return Math.max(map.getOrDefault(k, new Enty<>(0, null, null)).maxtime - System.currentTimeMillis(), 0); + }, null, null); + } + + /** + * 统一检查并移除过期数据 + *

+ * 通过占用锁并扫描全部数据来彻底剔除已经过期的数据,时间点以函数开始运行的时间点为准。 + */ + public + void trimData() { + LOCK.write(() -> { + long nowtime = System.currentTimeMillis(); + var iter = map.entrySet().iterator(); + // 检查 + while( iter.hasNext() ) + CheckVal(iter, nowtime); + }, null, null); + } + + /** 关闭检查线程 */ + public + void closeTimeTask() { + if ( timerRun != null ) + timerRun.cancel(); + } + + /** + * 关闭检查线程并清除数据 + * + * @see #closeTimeTask() + * @see #clear() + */ + public + void closeTimeTaskAndClear() { + closeTimeTask(); + clear(); + getGcThread().shutdown(); + } + + /** + * 检查并移除已经过期的数据 + * + * @since 0.0.2 + */ + private + void CheckVal(Iterator>> iter, long nowtime) { + // 当前节点 + var v = iter.next(); + var val = v.getValue(); + // 检查是否最大时间 + if ( val.maxtime <= nowtime ) { + // 移除 + iter.remove(); + // 异步执行回收事件 + GcVal(val); } - - /** - * 检查数据是否可用 - * - * @param k 数据的键 - * - * @return 可用为 true - */ - public - boolean checkData(@NotNull K k) { return LOCK.read(() -> check(k)); } - - /** 检查数据是否可用 */ - protected - boolean check(@NotNull K k) - { return map.getOrDefault(k, new Enty<>(0, null, null)).maxtime > System.currentTimeMillis(); } - - //------------------------------------- - - /** - * 获取数据剩余的存活时间 - * - * @param k 数据的键 - * - * @return 剩余时间(毫秒),过期为 0 - */ + } + + /** + * 申请执行当前数据的回收事件 + * + * @since 0.0.2 + */ + private + void GcVal(Enty v) { + if ( v == null ) + return; + // 当前回收事件 + val endrun = v.getEndrun(); + // 线程池执行 + getGcThread().submit(() -> { + if ( endrun != null ) + endrun.accept(v.getVal()); + }); + } + + /** + * 获取缓存构造工具 + * + * @param 键的类型 + * @param 缓存内容的类型 + * + * @return 构造工具 + */ + @NotNull + public static + Build build(Class kClass, Class vClass) { return new Build<>(); } + + /** + *

{@link TimeMapCache} 构造工具.

+ *
    + *
  • 使用 {@link #lockBy(SyLock)} 绑定并发管理
  • + *
  • 使用 {@link #dataTime(long)} 指定数据存活时间
  • + *
  • 使用 {@link #scarrentime(long)} 指定扫描间隔时间
  • + *
  • 使用 {@link #scarrenNum(int)} 指定扫描数量
  • + *
  • 使用 {@link #build()} 进行构造
  • + *
+ * + * @version 0.0.1 + * @since TimeMapCache 0.0.1 + */ + @Accessors(chain = true, fluent = true) + public static final + class Build { + /** 并发工具 */ + @Setter protected SyLock lockBy = new ObjLock(); + /** 默认数据存活时间 */ + @Setter protected long dataTime = 5 * 60000; + /** 扫描时检查的数量 */ + @Setter protected int scarrenNum = 20; + /** 扫描间隔时间 */ + @Setter protected long scarrentime = 24 * 60 * 600000; + + /** 构造 */ + @NotNull public - long dataHasTime(@NotNull K k) { - return LOCK.read(() -> Math.max(map.getOrDefault(k, new Enty<>(0, null, null)).maxtime - - System.currentTimeMillis(), 0)); + TimeMapCache build() { + var c = new TimeMapCache(lockBy, dataTime, scarrentime); + c.setScarrenNum(scarrenNum); + return c; } - + } + + /** + *

数据记录对象.

+ * + * @author fybug + * @version 0.0.2 + * @since TimeMapCache 0.0.1 + */ + @AllArgsConstructor + @Setter + @Getter + public static + class Enty { + /** 过期的时间 */ + public long maxtime; + /** 数据 */ + @Nullable public V val; /** - * 统一检查并移除过期数据 + * 回收时的处理 *

- * 通过占用锁并扫描全部数据来彻底剔除已经过期的数据,时间点以函数开始运行的时间点为准。 - */ - public - void trimData() { - LOCK.write(() -> { - long nowtime = System.currentTimeMillis(); - var iter = map.entrySet().iterator(); - // 检查 - while( iter.hasNext() ) - CheckVal(iter, nowtime); - }); - } - - /** 关闭检查线程 */ - public - void closeTimeTask() { - if (timerRun != null) - timerRun.cancel(); - } - - /** - * 关闭检查线程并清除数据 - * - * @see #closeTimeTask() - * @see #clear() - */ - public - void closeTimeTaskAndClear() { - closeTimeTask(); - clear(); - getGcThread().shutdown(); - } - - /*--------------------------------------------------------------------------------------------*/ - - /** - * 检查并移除已经过期的数据 - * - * @since 0.0.2 - */ - private - void CheckVal(Iterator>> iter, long nowtime) { - // 当前节点 - var v = iter.next(); - var val = v.getValue(); - // 检查是否最大时间 - if (val.maxtime <= nowtime) { - // 移除 - iter.remove(); - // 异步执行回收事件 - GcVal(val); - } - } - - /** - * 申请执行当前数据的回收事件 + * 接口传入当前数据 * * @since 0.0.2 */ - private - void GcVal(Enty v) { - if (v == null) - return; - // 当前回收事件 - val endrun = v.getEndrun(); - // 线程池执行 - getGcThread().submit(() -> { - if (endrun != null) - endrun.accept(v.getVal()); - }); - } - - /*--------------------------------------------------------------------------------------------*/ - - /** - * 获取缓存构造工具 - * - * @param 键的类型 - * @param 缓存内容的类型 - * - * @return 构造工具 - */ - @NotNull - public static - Build build(Class kClass, Class vClass) { return new Build<>(); } - - /** - *

{@link TimeMapCache} 构造工具.

- *
    - *
  • 使用 {@link #lockBy(SyLock)} 绑定并发管理
  • - *
  • 使用 {@link #dataTime(long)} 指定数据存活时间
  • - *
  • 使用 {@link #scarrentime(long)} 指定扫描间隔时间
  • - *
  • 使用 {@link #scarrenNum(int)} 指定扫描数量
  • - *
  • 使用 {@link #build()} 进行构造
  • - *
- * - * @version 0.0.1 - * @since TimeMapCache 0.0.1 - */ - @Accessors( chain = true, fluent = true ) - public static final - class Build { - /** 并发工具 */ - @Setter protected SyLock lockBy = new ObjLock(); - /** 默认数据存活时间 */ - @Setter protected long dataTime = 5 * 60000; - /** 扫描时检查的数量 */ - @Setter protected int scarrenNum = 20; - /** 扫描间隔时间 */ - @Setter protected long scarrentime = 24 * 60 * 600000; - - /** 构造 */ - @NotNull - public - TimeMapCache build() { - var c = new TimeMapCache(lockBy, dataTime, scarrentime); - c.setScarrenNum(scarrenNum); - return c; - } - } - - //---------------------------------------------------------------------------------------------- - - /** - *

数据记录对象.

- * - * @author fybug - * @version 0.0.2 - * @since TimeMapCache 0.0.1 - */ - @AllArgsConstructor - @Setter - @Getter - public static - class Enty { - /** 过期的时间 */ - public long maxtime; - /** 数据 */ - @Nullable public V val; - /** - * 回收时的处理 - *

- * 接口传入当前数据 - * - * @since 0.0.2 - */ - @Nullable public Consumer endrun; - } + @Nullable public Consumer endrun; + } } diff --git a/src/main/java/fybug/nulll/pdcache/supplier/LockCache.java b/src/main/java/fybug/nulll/pdcache/supplier/LockCache.java index f4b6801979563b4b5fb101ba06a89b9c87d2a32b..4f7951d1238cc54048c5f1cdc78ad51141866ee1 100644 --- a/src/main/java/fybug/nulll/pdcache/supplier/LockCache.java +++ b/src/main/java/fybug/nulll/pdcache/supplier/LockCache.java @@ -1,12 +1,11 @@ package fybug.nulll.pdcache.supplier; -import org.jetbrains.annotations.NotNull; - import java.lang.ref.Reference; import java.lang.ref.SoftReference; import java.util.function.Supplier; -import fybug.nulll.pdconcurrent.ObjLock; import fybug.nulll.pdconcurrent.SyLock; +import fybug.nulll.pdconcurrent.lock.ObjLock; +import jakarta.validation.constraints.NotNull; import lombok.Setter; import lombok.experimental.Accessors; @@ -24,88 +23,82 @@ import lombok.experimental.Accessors; */ public class LockCache extends SCache { - /** 缓存的锁的生成方法 */ - private final Supplier LOCK_SUPP; + /** 缓存的锁的生成方法 */ + private final Supplier LOCK_SUPP; - /** - * 构造缓存,指定缓存方式和缓存的锁类型 - * - * @see #LockCache(Class, Supplier) - */ - public - LockCache(@NotNull Class refc, @NotNull Class Locktype) { - this(refc, new SyLockSupp(Locktype)); - } + /** + * 构造缓存,指定缓存方式和缓存的锁类型 + * + * @see #LockCache(Class, Supplier) + */ + public + LockCache(@NotNull Class refc, @NotNull Class Locktype) { + this(refc, new SyLockSupp(Locktype)); + } - /** 构造缓存,指定缓存方式和缓存的锁的生成方法 */ - public - LockCache(@NotNull Class refc, @NotNull Supplier lockSupplier) { - super(refc, SyLock.newObjLock()); - LOCK_SUPP = lockSupplier; - } + /** 构造缓存,指定缓存方式和缓存的锁的生成方法 */ + public + LockCache(@NotNull Class refc, @NotNull Supplier lockSupplier) { + super(refc, SyLock.newObjLock()); + LOCK_SUPP = lockSupplier; + } - /*--------------------------------------------------------------------------------------------*/ + @NotNull + @Override + protected + SyLock createData() { return LOCK_SUPP.get(); } - @NotNull - @Override - protected - SyLock createData() { return LOCK_SUPP.get(); } + /** + * 获取构造工具 + * + * @return 构造工具 + */ + public static + Build build() { return new Build(); } - /*--------------------------------------------------------------------------------------------*/ + /** + *

{@link LockCache} 构造工具.

+ *
    + *
  • 使用 {@link #refernce(Class)} 绑定缓存方式
  • + *
  • 使用 {@link #sylock(Class)} 绑定缓存的锁的类型
  • + *
  • 使用 {@link #sylock(Supplier)} 绑定缓存的锁的生成方法
  • + *
  • 使用 {@link #build()} 进行构造
  • + *
+ * + * @version 0.0.1 + * @since LockCache 0.0.1 + */ + @Accessors(chain = true, fluent = true) + public final static + class Build { + /** 缓存引用类型 */ + @Setter private Class refernce = SoftReference.class; + /** 缓存的锁的生成方法 */ + private Supplier sylock = ObjLock::new; /** - * 获取构造工具 + * 设置缓存的锁类型 * - * @return 构造工具 + * @see #sylock(Supplier) */ - public static - Build build() { return new Build(); } + @NotNull + public + Build sylock(Class sylock) { return sylock(new SyLockSupp(sylock)); } + + /** 设置缓存的锁的生成方法 */ + public + Build sylock(@NotNull Supplier syLockSupplier) { + this.sylock = syLockSupplier; + return this; + } /** - *

{@link LockCache} 构造工具.

- *
    - *
  • 使用 {@link #refernce(Class)} 绑定缓存方式
  • - *
  • 使用 {@link #sylock(Class)} 绑定缓存的锁的类型
  • - *
  • 使用 {@link #sylock(Supplier)} 绑定缓存的锁的生成方法
  • - *
  • 使用 {@link #build()} 进行构造
  • - *
+ * 构造锁缓存 * - * @version 0.0.1 - * @since LockCache 0.0.1 + * @return 锁缓存工具 */ - @Accessors( chain = true, fluent = true ) - public final static - class Build { - /** 缓存引用类型 */ - @Setter private Class refernce = SoftReference.class; - /** 缓存的锁的生成方法 */ - private Supplier sylock = ObjLock::new; - - //------------------------------------------------------------------------------------------ - - /** - * 设置缓存的锁类型 - * - * @see #sylock(Supplier) - */ - @NotNull - public - Build sylock(Class sylock) { return sylock(new SyLockSupp(sylock)); } - - /** 设置缓存的锁的生成方法 */ - public - Build sylock(@NotNull Supplier syLockSupplier) { - this.sylock = syLockSupplier; - return this; - } - - /** - * 构造锁缓存 - * - * @return 锁缓存工具 - */ - @NotNull - public - LockCache build() { return new LockCache(refernce, sylock); } - } + @NotNull + public + LockCache build() { return new LockCache(refernce, sylock); } + } } diff --git a/src/main/java/fybug/nulll/pdcache/supplier/LockMapCache.java b/src/main/java/fybug/nulll/pdcache/supplier/LockMapCache.java index 3b1c76b60edfc2d138ac781faa42733a412b5182..46ba885e3776aa68f228ccdcea1fe078262a58c9 100644 --- a/src/main/java/fybug/nulll/pdcache/supplier/LockMapCache.java +++ b/src/main/java/fybug/nulll/pdcache/supplier/LockMapCache.java @@ -1,12 +1,11 @@ package fybug.nulll.pdcache.supplier; -import org.jetbrains.annotations.NotNull; - import java.lang.ref.Reference; import java.lang.ref.SoftReference; import java.util.function.Supplier; -import fybug.nulll.pdconcurrent.ObjLock; import fybug.nulll.pdconcurrent.SyLock; +import fybug.nulll.pdconcurrent.lock.ObjLock; +import jakarta.validation.constraints.NotNull; import lombok.Setter; import lombok.experimental.Accessors; @@ -26,93 +25,87 @@ import lombok.experimental.Accessors; */ public class LockMapCache extends SMapCache { - /** 缓存的锁的生成方法 */ - private final Supplier LOCK_SUPP; + /** 缓存的锁的生成方法 */ + private final Supplier LOCK_SUPP; - /** - * 构造缓存,指定缓存方式和缓存的锁类型 - * - * @see #LockMapCache(Class, Supplier) - */ - public - LockMapCache(@NotNull Class refc, @NotNull Class syLock) - { this(refc, new SyLockSupp(syLock)); } + /** + * 构造缓存,指定缓存方式和缓存的锁类型 + * + * @see #LockMapCache(Class, Supplier) + */ + public + LockMapCache(@NotNull Class refc, @NotNull Class syLock) + { this(refc, new SyLockSupp(syLock)); } - /** 构造缓存,指定缓存方式和缓存的锁的生成方法 */ - public - LockMapCache(@NotNull Class refc, @NotNull Supplier syLockSupplier) - { - super(refc, SyLock.newObjLock()); - LOCK_SUPP = syLockSupplier; - } + /** 构造缓存,指定缓存方式和缓存的锁的生成方法 */ + public + LockMapCache(@NotNull Class refc, @NotNull Supplier syLockSupplier) + { + super(refc, SyLock.newObjLock()); + LOCK_SUPP = syLockSupplier; + } - /*--------------------------------------------------------------------------------------------*/ + @NotNull + @Override + protected + SyLock createData(@NotNull K key) { return LOCK_SUPP.get(); } - @NotNull - @Override - protected - SyLock createData(@NotNull K key) { return LOCK_SUPP.get(); } + /** + * 获取构造工具 + * + * @param 缓存的键类型 + * + * @return 构造工具 + */ + public static + Build build(Class kcla) { return new Build<>(); } - /*--------------------------------------------------------------------------------------------*/ + /** + *

{@link LockMapCache} 构造工具.

+ *
    + *
  • 使用 {@link #refernce(Class)} 绑定缓存方式
  • + *
  • 使用 {@link #sylock(Class)} 绑定缓存的锁的类型
  • + *
  • 使用 {@link #sylock(Supplier)} 绑定缓存的锁的生成方法
  • + *
  • 使用 {@link #build()} 进行构造
  • + *
+ * + * @param 缓存键类型 + * + * @version 0.0.1 + * @since LockMapCache 0.0.1 + */ + @Accessors(chain = true, fluent = true) + public final static + class Build { + /** 缓存引用类型 */ + @Setter private Class refernce = SoftReference.class; + /** 缓存的锁的生成方法 */ + private Supplier sylock = ObjLock::new; /** - * 获取构造工具 - * - * @param 缓存的键类型 + * 设置缓存的锁类型 * - * @return 构造工具 + * @see #sylock(Supplier) */ - public static - Build build(Class kcla) { return new Build<>(); } + @NotNull + public + Build sylock(Class sylock) + { return sylock(new SyLockSupp(sylock)); } + + /** 设置缓存的锁的生成方法 */ + public + Build sylock(@NotNull Supplier syLockSupplier) { + this.sylock = syLockSupplier; + return this; + } /** - *

{@link LockMapCache} 构造工具.

- *
    - *
  • 使用 {@link #refernce(Class)} 绑定缓存方式
  • - *
  • 使用 {@link #sylock(Class)} 绑定缓存的锁的类型
  • - *
  • 使用 {@link #sylock(Supplier)} 绑定缓存的锁的生成方法
  • - *
  • 使用 {@link #build()} 进行构造
  • - *
- * - * @param 缓存键类型 + * 构造锁缓存 * - * @version 0.0.1 - * @since LockMapCache 0.0.1 + * @return 锁缓存工具 */ - @Accessors( chain = true, fluent = true ) - public final static - class Build { - /** 缓存引用类型 */ - @Setter private Class refernce = SoftReference.class; - /** 缓存的锁的生成方法 */ - private Supplier sylock = ObjLock::new; - - //------------------------------------------------------------------------------------------ - - /** - * 设置缓存的锁类型 - * - * @see #sylock(Supplier) - */ - @NotNull - public - Build sylock(Class sylock) - { return sylock(new SyLockSupp(sylock)); } - - /** 设置缓存的锁的生成方法 */ - public - Build sylock(@NotNull Supplier syLockSupplier) { - this.sylock = syLockSupplier; - return this; - } - - /** - * 构造锁缓存 - * - * @return 锁缓存工具 - */ - @NotNull - public - LockMapCache build() { return new LockMapCache<>(refernce, sylock); } - } + @NotNull + public + LockMapCache build() { return new LockMapCache<>(refernce, sylock); } + } } diff --git a/src/main/java/fybug/nulll/pdcache/supplier/SCache.java b/src/main/java/fybug/nulll/pdcache/supplier/SCache.java index c533f218852edff95670d36195833b6f37f63c86..7f5be35b5b2cadc9645b46d0e4e986ddd8480d76 100644 --- a/src/main/java/fybug/nulll/pdcache/supplier/SCache.java +++ b/src/main/java/fybug/nulll/pdcache/supplier/SCache.java @@ -1,6 +1,4 @@ package fybug.nulll.pdcache.supplier; -import org.jetbrains.annotations.NotNull; - import java.lang.ref.Reference; import fybug.nulll.pdcache.CacheOb; @@ -9,6 +7,7 @@ import fybug.nulll.pdcache.memory.Cache; import fybug.nulll.pdconcurrent.SyLock; import fybug.nulll.pdconcurrent.fun.tryConsumer; import fybug.nulll.pdconcurrent.fun.trySupplier; +import jakarta.validation.constraints.NotNull; import lombok.Setter; import lombok.experimental.Accessors; @@ -60,95 +59,91 @@ import lombok.experimental.Accessors; public abstract class SCache extends MemoryCache { - /** - * 构造缓存,指定缓存方式 - * - * @since 0.0.2 - */ - public - SCache(@NotNull Class refc) {super(refc); } + /** + * 构造缓存,指定缓存方式 + * + * @since 0.0.2 + */ + public + SCache(@NotNull Class refc) { super(refc); } - /** - * 构造缓存,指定缓存方式和并发管理 - * - * @since 0.0.3 - */ - public - SCache(@NotNull Class refc, @NotNull SyLock syLock) - { super(refc, syLock); } + /** + * 构造缓存,指定缓存方式和并发管理 + * + * @since 0.0.3 + */ + public + SCache(@NotNull Class refc, @NotNull SyLock syLock) + { super(refc, syLock); } - //---------------------------------------------------------------------------------------------- + //---------------------------------------------------------------------------------------------- - @Override - @NotNull - public - V get(@NotNull tryConsumer run) throws Exception { return super.get(run); } + @Override + @NotNull + public + V get(@NotNull tryConsumer run) throws Exception { return super.get(run); } - @Override - @NotNull - public - V get() throws Exception { return super.get(); } + @Override + @NotNull + public + V get() throws Exception { return super.get(); } - //----------------------------------- + /** 创建新的数据 */ + @NotNull + protected abstract + V createData() throws Exception; - /** 创建新的数据 */ - @NotNull - protected abstract - V createData() throws Exception; + /** + * 生成新的缓存 + *

+ * 使用 {@link #createData()} 创建的数据生成 + */ + @Override + protected @NotNull + V emptyData() throws Exception { + // 生成新的数据 + var v = createData(); + // 绑定缓存 + putdata(v); + return v; + } - /** - * 生成新的缓存 - *

- * 使用 {@link #createData()} 创建的数据生成 - */ - @Override - protected @NotNull - V emptyData() throws Exception { - // 生成新的数据 - var v = createData(); - // 绑定缓存 - putdata(v); - return v; - } + /** + * 获取缓存构造工具 + * + * @param 缓存内容的类型 + * + * @return 构造工具 + */ + @NotNull + public static + Build build(Class vc) { return new Build<>(); } - /*--------------------------------------------------------------------------------------------*/ + /** + *

{@link SCache} 构造工具.

+ *
    + *
  • 使用 {@link #createdata(trySupplier)} 绑定数据生成接口
  • + *
  • 使用 {@link #refernce(Class)} 绑定缓存方式
  • + *
  • 使用 {@link #lockBy(SyLock)} 绑定并发管理
  • + *
  • 使用 {@link #build()} 进行构造
  • + *
+ * + * @version 0.0.1 + * @since SCache 0.0.1 + */ + @Accessors(chain = true, fluent = true) + public final static + class Build extends CacheOb.Build> { + /** 数据生产接口 */ + @Setter private trySupplier<@NotNull V> createdata; - /** - * 获取缓存构造工具 - * - * @param 缓存内容的类型 - * - * @return 构造工具 - */ @NotNull - public static - Build build(Class vc) {return new Build<>();} - - /** - *

{@link SCache} 构造工具.

- *
    - *
  • 使用 {@link #createdata(trySupplier)} 绑定数据生成接口
  • - *
  • 使用 {@link #refernce(Class)} 绑定缓存方式
  • - *
  • 使用 {@link #lockBy(SyLock)} 绑定并发管理
  • - *
  • 使用 {@link #build()} 进行构造
  • - *
- * - * @version 0.0.1 - * @since SCache 0.0.1 - */ - @Accessors( chain = true, fluent = true ) - public final static - class Build extends CacheOb.Build> { - /** 数据生产接口 */ - @Setter private trySupplier<@NotNull V, Exception> createdata; - - @NotNull - public - SCache build() { - return new SCache<>(refernce, lockBy) { - protected @NotNull - V createData() throws Exception { return createdata.get(); } - }; - } + public + SCache build() { + return new SCache<>(refernce, lockBy) { + protected @NotNull + V createData() throws Exception { return createdata.get(); } + }; } + } } diff --git a/src/main/java/fybug/nulll/pdcache/supplier/SMapCache.java b/src/main/java/fybug/nulll/pdcache/supplier/SMapCache.java index cd8d386a41d620a92614994b4eec55c43e7da9ce..a1416f569a7300f7367676c01be69c006681f796 100644 --- a/src/main/java/fybug/nulll/pdcache/supplier/SMapCache.java +++ b/src/main/java/fybug/nulll/pdcache/supplier/SMapCache.java @@ -1,14 +1,13 @@ package fybug.nulll.pdcache.supplier; -import org.jetbrains.annotations.NotNull; - import java.lang.ref.Reference; +import java.util.function.BiConsumer; import fybug.nulll.pdcache.MapCacheOb; import fybug.nulll.pdcache.MemoryMapCache; import fybug.nulll.pdcache.err.CacheError; import fybug.nulll.pdconcurrent.SyLock; -import fybug.nulll.pdconcurrent.fun.tryBiConsumer; import fybug.nulll.pdconcurrent.fun.tryFunction; +import jakarta.validation.constraints.NotNull; import lombok.Setter; import lombok.experimental.Accessors; @@ -61,86 +60,80 @@ import lombok.experimental.Accessors; public abstract class SMapCache extends MemoryMapCache { - /** 构造缓存,指定缓存方式 */ - public - SMapCache(@NotNull Class refc) { super(refc); } - - /** 构造缓存,指定缓存方式和并发管理 */ - public - SMapCache(@NotNull Class refc, @NotNull SyLock syLock) - { super(refc, syLock); } - - //---------------------------------------------------------------------------------------------- + /** 构造缓存,指定缓存方式 */ + public + SMapCache(@NotNull Class refc) { super(refc); } + + /** 构造缓存,指定缓存方式和并发管理 */ + public + SMapCache(@NotNull Class refc, @NotNull SyLock syLock) + { super(refc, syLock); } + + @Override + @NotNull + public + V get(@NotNull K key) throws Exception, CacheError { return super.get(key); } + + @Override + @NotNull + public + V get(@NotNull K key, @NotNull BiConsumer run) throws Exception, CacheError + { return super.get(key, run); } + + /** 创建新的数据 */ + @NotNull + protected abstract + V createData(@NotNull K key) throws Exception; + + @NotNull + protected final + V emptyData(@NotNull K key) throws Exception, CacheError { + if ( isClose() ) + throw new CacheError(); + + // 生成新的数据 + var v = createData(key); + putdata(key, v); + return v; + } + + /** + * 获取缓存构造工具 + * + * @param 键的类型 + * @param 缓存内容的类型 + * + * @return 构造工具 + */ + @NotNull + public static + Build build(Class kc, Class vc) { return new Build<>(); } + + /** + *

{@link SMapCache} 构造工具.

+ *
    + *
  • 使用 {@link #createdata(tryFunction)} 方法绑定数据生成接口
  • + *
  • 使用 {@link #refernce(Class)} 绑定缓存方式
  • + *
  • 使用 {@link #lockBy(SyLock)} 绑定并发管理
  • + *
  • 使用 {@link #build()} 进行构造
  • + *
+ * + * @version 0.0.1 + * @since SMapCache 0.0.1 + */ + @Accessors(chain = true, fluent = true) + public static final + class Build extends MapCacheOb.Build> { + /** 数据生成接口 */ + @Setter private tryFunction<@NotNull K, @NotNull V> createdata; - @Override @NotNull public - V get(@NotNull K key) throws Exception, CacheError { return super.get(key); } - - @Override - @NotNull - public - V get(@NotNull K key, @NotNull tryBiConsumer run) throws Exception, CacheError - { return super.get(key, run); } - - //-------------------------------- - - /** 创建新的数据 */ - @NotNull - protected abstract - V createData(@NotNull K key) throws Exception; - - @NotNull - protected final - V emptyData(@NotNull K key) throws Exception, CacheError { - if (isClose()) - throw new CacheError(); - - // 生成新的数据 - var v = createData(key); - putdata(key, v); - return v; - } - - /*--------------------------------------------------------------------------------------------*/ - - /** - * 获取缓存构造工具 - * - * @param 键的类型 - * @param 缓存内容的类型 - * - * @return 构造工具 - */ - @NotNull - public static - Build build(Class kc, Class vc) {return new Build<>();} - - /** - *

{@link SMapCache} 构造工具.

- *
    - *
  • 使用 {@link #createdata(tryFunction)} 方法绑定数据生成接口
  • - *
  • 使用 {@link #refernce(Class)} 绑定缓存方式
  • - *
  • 使用 {@link #lockBy(SyLock)} 绑定并发管理
  • - *
  • 使用 {@link #build()} 进行构造
  • - *
- * - * @version 0.0.1 - * @since SMapCache 0.0.1 - */ - @Accessors( chain = true, fluent = true ) - public static final - class Build extends MapCacheOb.Build> { - /** 数据生成接口 */ - @Setter private tryFunction<@NotNull K, @NotNull V, Exception> createdata; - - @NotNull - public - SMapCache build() { - return new SMapCache<>(refernce, lockBy) { - protected @NotNull - V createData(@NotNull K key) throws Exception { return createdata.apply(key); } - }; - } + SMapCache build() { + return new SMapCache<>(refernce, lockBy) { + protected @NotNull + V createData(@NotNull K key) throws Exception { return createdata.apply(key); } + }; } + } } diff --git a/src/main/java/fybug/nulll/pdcache/supplier/SyLockSupp.java b/src/main/java/fybug/nulll/pdcache/supplier/SyLockSupp.java index e3602cfbc4339bacf7776996e35483455a66eb7e..985abe6f4a79ff48e154751f9a5153982b34d770 100644 --- a/src/main/java/fybug/nulll/pdcache/supplier/SyLockSupp.java +++ b/src/main/java/fybug/nulll/pdcache/supplier/SyLockSupp.java @@ -15,20 +15,20 @@ import fybug.nulll.pdconcurrent.SyLock; */ final class SyLockSupp implements Supplier { - // 锁的类型 - private final Class LOCK_CLASS; + // 锁的类型 + private final Class LOCK_CLASS; - /** 指定锁的类 */ - SyLockSupp(Class sylock) { LOCK_CLASS = sylock; } + /** 指定锁的类 */ + SyLockSupp(Class sylock) { LOCK_CLASS = sylock; } - @Override - public - SyLock get() { - try { - return LOCK_CLASS.getConstructor().newInstance(); - } catch ( Exception e ) { - e.printStackTrace(); - } - return SyLock.newObjLock(); + @Override + public + SyLock get() { + try { + return LOCK_CLASS.getConstructor().newInstance(); + } catch ( Exception e ) { + e.printStackTrace(); } + return SyLock.newObjLock(); + } } diff --git a/src/test/java/fybug/nulll/pdcache/RunTest.java b/src/test/java/fybug/nulll/pdcache/RunTest.java deleted file mode 100644 index bad646085c175a3c89686f1d4e0de05baf4e4297..0000000000000000000000000000000000000000 --- a/src/test/java/fybug/nulll/pdcache/RunTest.java +++ /dev/null @@ -1,46 +0,0 @@ -package fybug.nulll.pdcache; -import org.junit.Assert; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringWriter; - -import fybug.nulll.pdcache.memory.memoryTest; -import fybug.nulll.pdcache.supplier.suppilerTest; - -@RunWith( Suite.class ) -@Suite.SuiteClasses( {memoryTest.class, suppilerTest.class} ) -public -class RunTest { - public static PrintWriter from; - public static PrintWriter to; - - public static StringWriter from_s; - public static StringWriter to_s; - - public static - void init() { - from = new PrintWriter(from_s = new StringWriter()); - to = new PrintWriter(to_s = new StringWriter()); - } - - public static - void destruction() throws IOException { - suppilerTest.destruction(); - - from.close(); - from = null; - from_s.close(); - from_s = null; - - to.close(); - to = null; - to_s.close(); - to_s = null; - } - - public static - void check() { Assert.assertEquals(from_s.toString(), to_s.toString()); } -} diff --git a/src/test/java/fybug/nulll/pdcache/memory/CacheTest.java b/src/test/java/fybug/nulll/pdcache/memory/CacheTest.java deleted file mode 100644 index fa4874b99416adf3a12d26b954c383ee837a0058..0000000000000000000000000000000000000000 --- a/src/test/java/fybug/nulll/pdcache/memory/CacheTest.java +++ /dev/null @@ -1,67 +0,0 @@ -package fybug.nulll.pdcache.memory; -import org.jetbrains.annotations.NotNull; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import java.io.IOException; -import java.lang.ref.WeakReference; - -import fybug.nulll.pdcache.CanClean; -import fybug.nulll.pdcache.PDCache; - -import static fybug.nulll.pdcache.RunTest.check; -import static fybug.nulll.pdcache.RunTest.destruction; -import static fybug.nulll.pdcache.RunTest.from; -import static fybug.nulll.pdcache.RunTest.init; -import static fybug.nulll.pdcache.RunTest.to; - -public -class CacheTest { - private Cache cache; - - @Before - public - void setUp() { - init(); - cache = PDCache.Cache(Object.class).refernce(WeakReference.class).build(); - } - - @After - public - void tearDown() throws IOException { - cache.clear(); - cache = null; - destruction(); - } - - @Test - public - void cache() throws Exception { - CanClean o = new CanClean() { - public @NotNull - Runnable getclean() { return () -> to.println("des:"); } - }; - - from.println(o); - cache.set(o); - cache.get(to::println); - - o = null; - System.gc(); - from.println("des:"); - from.println("null"); - cache.get(to::println); - - o = new CanClean() { - public @NotNull - Runnable getclean() { return () -> {}; } - }; - - from.println(o); - cache.set(o); - cache.get(to::println); - - check(); - } -} \ No newline at end of file diff --git a/src/test/java/fybug/nulll/pdcache/memory/MapCacheTest.java b/src/test/java/fybug/nulll/pdcache/memory/MapCacheTest.java deleted file mode 100644 index 4f43c076c67e172dd07d7c185a3523fb7a6b0833..0000000000000000000000000000000000000000 --- a/src/test/java/fybug/nulll/pdcache/memory/MapCacheTest.java +++ /dev/null @@ -1,72 +0,0 @@ -package fybug.nulll.pdcache.memory; -import org.jetbrains.annotations.NotNull; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import java.io.IOException; -import java.lang.ref.WeakReference; - -import fybug.nulll.pdcache.CanClean; -import fybug.nulll.pdcache.PDCache; - -import static fybug.nulll.pdcache.RunTest.check; -import static fybug.nulll.pdcache.RunTest.destruction; -import static fybug.nulll.pdcache.RunTest.from; -import static fybug.nulll.pdcache.RunTest.init; -import static fybug.nulll.pdcache.RunTest.to; - -public -class MapCacheTest { - private MapCache cache; - - @Before - public - void setUp() { - init(); - cache = PDCache.MapCache(String.class, Object.class).refernce(WeakReference.class).build(); - } - - @After - public - void tearDown() throws IOException { - cache.clear(); - cache = null; - destruction(); - } - - @Test - public - void cache() throws Exception { - CanClean o = new CanClean() { - public @NotNull - Runnable getclean() { - return () -> to.println("des:"); - } - }; - - from.println(o); - cache.put("asd", o); - cache.get("asd", (k, v) -> to.println(v)); - - // 模拟回收 - o = null; - System.gc(); - from.println("des:"); - from.println("null"); - cache.get("asd", (k, v) -> to.println(v)); - - o = new CanClean() { - public @NotNull - Runnable getclean() { - return () -> {}; - } - }; - - from.println(o); - cache.put("asd", o); - cache.get("asd", (k, v) -> to.println(v)); - - check(); - } -} \ No newline at end of file diff --git a/src/test/java/fybug/nulll/pdcache/memory/TimeMapCacheTest.java b/src/test/java/fybug/nulll/pdcache/memory/TimeMapCacheTest.java deleted file mode 100644 index e3fa3206fdc080a1934097b4c6e66f9296d6aa29..0000000000000000000000000000000000000000 --- a/src/test/java/fybug/nulll/pdcache/memory/TimeMapCacheTest.java +++ /dev/null @@ -1,69 +0,0 @@ -package fybug.nulll.pdcache.memory; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import fybug.nulll.pdcache.PDCache; - -public -class TimeMapCacheTest { - TimeMapCache cache; - - @Before - public - void setUp() { - cache = PDCache.TimeMapCache(String.class, String.class) - .dataTime(1000) - .scarrenNum(2) - .scarrentime(500) - .build(); - } - - @After - public - void tearDown() { cache.closeTimeTaskAndClear(); } - - // 获取过期测试 - @Test - public - void getTest() throws InterruptedException { - cache.putData("a", "1", 2000); - cache.putData("b", "2"); - cache.putData("c", "3"); - cache.putData("d", "4"); - cache.putData("e", "5"); - cache.putData("f", "6"); - - Thread.sleep(1100); - - assert "1".equals(cache.getData("a")); - assert null == cache.getData("b"); - assert null == cache.getData("c"); - assert null == cache.getData("d"); - assert null == cache.getData("e"); - assert null == cache.getData("f"); - } - - // 扫描线程测试 - @Test - public - void timeTest() throws InterruptedException { - cache.putData("a", "1", 2000); - cache.putData("b", "2"); - cache.putData("c", "3"); - cache.putData("d", "4"); - cache.putData("e", "5"); - cache.putData("f", "6"); - - cache.getData("a"); - cache.getData("f"); - Thread.sleep(1500); - - cache.LOCK.read(() -> { - assert null != cache.map.get("a"); - assert null == cache.map.get("b"); - assert null == cache.map.get("c"); - assert null != cache.map.get("f"); - }); - } -} \ No newline at end of file diff --git a/src/test/java/fybug/nulll/pdcache/memory/memoryTest.java b/src/test/java/fybug/nulll/pdcache/memory/memoryTest.java deleted file mode 100644 index a619faf4db42a32ce792de60ea42a0aec6a7ab65..0000000000000000000000000000000000000000 --- a/src/test/java/fybug/nulll/pdcache/memory/memoryTest.java +++ /dev/null @@ -1,8 +0,0 @@ -package fybug.nulll.pdcache.memory; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -@RunWith( Suite.class ) -@Suite.SuiteClasses( {CacheTest.class, MapCacheTest.class, TimeMapCacheTest.class} ) -public -class memoryTest {} diff --git a/src/test/java/fybug/nulll/pdcache/supplier/SCacheTest.java b/src/test/java/fybug/nulll/pdcache/supplier/SCacheTest.java deleted file mode 100644 index be0c5eac2351c10ed005b66b3733d614a0546404..0000000000000000000000000000000000000000 --- a/src/test/java/fybug/nulll/pdcache/supplier/SCacheTest.java +++ /dev/null @@ -1,56 +0,0 @@ -package fybug.nulll.pdcache.supplier; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import java.io.IOException; -import java.lang.ref.WeakReference; - -import fybug.nulll.pdcache.PDCache; -import fybug.nulll.pdcache.supplier.SCache; -import fybug.nulll.pdcache.supplier.suppilerTest; - -import static fybug.nulll.pdcache.RunTest.check; -import static fybug.nulll.pdcache.RunTest.destruction; -import static fybug.nulll.pdcache.RunTest.from; -import static fybug.nulll.pdcache.RunTest.init; -import static fybug.nulll.pdcache.RunTest.to; -import static fybug.nulll.pdcache.supplier.suppilerTest.getNowClean; -import static fybug.nulll.pdcache.supplier.suppilerTest.nextClean; - -public -class SCacheTest { - private SCache cache; - - @Before - public - void setUp() { - init(); - cache = PDCache.SCache(Object.class) - .createdata(suppilerTest::getNowClean) - .refernce(WeakReference.class) - .build(); - } - - @After - public - void tearDown() throws IOException { - cache.clear(); - cache = null; - destruction(); - } - - @Test - public - void cache() throws Exception { - from.println(nextClean()); - cache.get(to::println); - - from.println("des:" + getNowClean().toString()); - from.println(nextClean()); - System.gc(); - cache.get(to::println); - - check(); - } -} \ No newline at end of file diff --git a/src/test/java/fybug/nulll/pdcache/supplier/SMapCacheTest.java b/src/test/java/fybug/nulll/pdcache/supplier/SMapCacheTest.java deleted file mode 100644 index f314c2208924d3f03402a657edd6e9b6bd7a7d10..0000000000000000000000000000000000000000 --- a/src/test/java/fybug/nulll/pdcache/supplier/SMapCacheTest.java +++ /dev/null @@ -1,57 +0,0 @@ -package fybug.nulll.pdcache.supplier; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import java.io.IOException; -import java.lang.ref.WeakReference; - -import fybug.nulll.pdcache.PDCache; -import fybug.nulll.pdcache.supplier.SMapCache; - -import static fybug.nulll.pdcache.RunTest.check; -import static fybug.nulll.pdcache.RunTest.destruction; -import static fybug.nulll.pdcache.RunTest.from; -import static fybug.nulll.pdcache.RunTest.init; -import static fybug.nulll.pdcache.RunTest.to; -import static fybug.nulll.pdcache.supplier.suppilerTest.getNowClean; -import static fybug.nulll.pdcache.supplier.suppilerTest.nextClean; - -public -class SMapCacheTest { - private SMapCache cache; - - @Before - public - void setUp() { - init(); - cache = PDCache.SMapCache(String.class, Object.class) - .createdata((k) -> getNowClean()) - .refernce(WeakReference.class) - .build(); - } - - @After - public - void tearDown() throws IOException { - cache.close(); - cache = null; - destruction(); - } - - @Test - public - void cache() throws Exception { - - from.println(nextClean()); - cache.get("asd", (k, v) -> to.println(v)); - - // 模拟回收 - from.println("des:" + getNowClean()); - from.println(nextClean()); - System.gc(); - cache.get("asd", (k, v) -> to.println(v)); - - check(); - } -} \ No newline at end of file diff --git a/src/test/java/fybug/nulll/pdcache/supplier/memoryTest.java b/src/test/java/fybug/nulll/pdcache/supplier/memoryTest.java deleted file mode 100644 index 599c556445ecdc0ef82bfa27dac495273f5703da..0000000000000000000000000000000000000000 --- a/src/test/java/fybug/nulll/pdcache/supplier/memoryTest.java +++ /dev/null @@ -1,8 +0,0 @@ -package fybug.nulll.pdcache.supplier; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -@RunWith( Suite.class ) -@Suite.SuiteClasses( {SCacheTest.class, SMapCacheTest.class} ) -public -class memoryTest {} diff --git a/src/test/java/fybug/nulll/pdcache/supplier/suppilerTest.java b/src/test/java/fybug/nulll/pdcache/supplier/suppilerTest.java deleted file mode 100644 index ab262258c4775cfe999cff219d904fcdfa9d19f8..0000000000000000000000000000000000000000 --- a/src/test/java/fybug/nulll/pdcache/supplier/suppilerTest.java +++ /dev/null @@ -1,37 +0,0 @@ -package fybug.nulll.pdcache.supplier; -import org.jetbrains.annotations.NotNull; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -import fybug.nulll.pdcache.CanClean; - -import static fybug.nulll.pdcache.RunTest.to; - -@RunWith( Suite.class ) -@Suite.SuiteClasses( {memoryTest.class} ) -public -class suppilerTest { - private static CanClean canClean = null; - - public static - CanClean getNowClean() { return canClean; } - - public static - CanClean nextClean() { return canClean = new a(); } - - public static - void destruction() { - canClean = null; - System.gc(); - } - - private static - class a implements CanClean { - - public @NotNull - Runnable getclean() { - var s = this.toString(); - return () -> to.println("des:" + s); - } - } -}